From linear-pack
Diagnose and fix common Linear API errors. Use when encountering Linear API errors, debugging integration issues, or troubleshooting authentication problems. Trigger with phrases like "linear error", "linear API error", "debug linear", "linear not working", "linear authentication error".
How this skill is triggered — by the user, by Claude, or both
Slash command
/linear-pack:linear-common-errorsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Quick reference for diagnosing and resolving common Linear API errors.
Quick reference for diagnosing and resolving common Linear API errors.
Error: Authentication required
Code: UNAUTHENTICATED
Causes:
lin_api_)Solutions:
// Verify key format
const apiKey = process.env.LINEAR_API_KEY;
if (!apiKey?.startsWith("lin_api_")) {
console.error("Invalid API key format");
}
// Test authentication
const client = new LinearClient({ apiKey });
try {
await client.viewer;
console.log("Authentication successful");
} catch (e) {
console.error("Authentication failed:", e);
}
Error: You don't have permission to access this resource
Code: FORBIDDEN
Causes:
Solutions:
Error: Rate limit exceeded
Code: RATE_LIMITED
Headers: X-RateLimit-Remaining: 0, Retry-After: 60
Causes:
Solutions:
// Implement exponential backoff
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error: any) {
if (error?.extensions?.code === "RATE_LIMITED" && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
console.log(`Rate limited, retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new Error("Max retries exceeded");
}
Error: Variable "$input" got invalid value
Code: BAD_USER_INPUT
Common Validation Failures:
| Field | Error | Fix |
|---|---|---|
teamId | "Team not found" | Verify team exists and accessible |
priority | "Invalid priority" | Use 0-4 (0=None, 1=Urgent, 4=Low) |
estimate | "Invalid estimate" | Use team's configured values |
stateId | "State not found" | State must belong to same team |
assigneeId | "User not found" | User must be team member |
Debug Validation:
async function createIssueWithValidation(input: {
teamId: string;
title: string;
stateId?: string;
assigneeId?: string;
}) {
// Validate team exists
const team = await client.team(input.teamId);
if (!team) throw new Error(`Team not found: ${input.teamId}`);
// Validate state belongs to team
if (input.stateId) {
const states = await team.states();
if (!states.nodes.find(s => s.id === input.stateId)) {
throw new Error(`State ${input.stateId} not in team ${team.key}`);
}
}
// Validate assignee is team member
if (input.assigneeId) {
const members = await team.members();
if (!members.nodes.find(m => m.id === input.assigneeId)) {
throw new Error(`User ${input.assigneeId} not in team ${team.key}`);
}
}
return client.createIssue(input);
}
Error: Cannot query field "nonExistent" on type "Issue"
Code: GRAPHQL_VALIDATION_FAILED
Causes:
Solutions:
# Update SDK to latest
npm update @linear/sdk
# Check API schema
curl -H "Authorization: $LINEAR_API_KEY" \
https://api.linear.app/graphql \
-d '{"query": "{ __schema { types { name } } }"}'
Error: fetch failed
Cause: ECONNREFUSED / ETIMEDOUT
Solutions:
// Add timeout and retry
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);
try {
const response = await fetch("https://api.linear.app/graphql", {
signal: controller.signal,
// ... other options
});
} finally {
clearTimeout(timeout);
}
curl -s -H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { name email } }"}' \
https://api.linear.app/graphql | jq
curl -I -H "Authorization: $LINEAR_API_KEY" \
https://api.linear.app/graphql
# Look for: X-RateLimit-Limit, X-RateLimit-Remaining
import crypto from "crypto";
function verifyWebhookSignature(
body: string,
signature: string,
secret: string
): boolean {
const hmac = crypto.createHmac("sha256", secret);
const digest = hmac.update(body).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
import { LinearClient, LinearError } from "@linear/sdk";
async function safeLinearCall<T>(
operation: () => Promise<T>,
context: string
): Promise<T> {
try {
return await operation();
} catch (error) {
if (error instanceof LinearError) {
console.error(`Linear API Error in ${context}:`, {
message: error.message,
type: error.type,
errors: error.errors,
});
// Handle specific error types
switch (error.type) {
case "AuthenticationError":
throw new Error("Please check your Linear API key");
case "RateLimitedError":
throw new Error("Too many requests, please retry later");
default:
throw error;
}
}
throw error;
}
}
Set up comprehensive debugging with linear-debug-bundle.
npx claudepluginhub p/jamon8888-linear-pack-plugins-saas-packs-linear-packGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Implements work from a spec or tickets using TDD at agreed seams, with regular typechecking and test runs, followed by code review.