linear-common-errors
Provides troubleshooting workflows for Linear API errors and SDK integration issues.
Install
mkdir -p .claude/skills/linear-common-errors && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6904" && unzip -o skill.zip -d .claude/skills/linear-common-errors && rm skill.zipInstalls to .claude/skills/linear-common-errors
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Diagnose and fix common Linear API and SDK errors.Key capabilities
- →Diagnose Linear API authentication errors
- →Implement retry logic for Linear rate limiting
- →Optimize GraphQL queries to reduce complexity
- →Handle entity not found errors in Linear
- →Validate input for Linear mutations
- →Verify Linear webhook signatures
How it works
This skill provides diagnostic steps and code examples to identify and resolve common Linear API errors, including authentication, rate limiting, query complexity, and input validation.
Inputs & outputs
When to use linear-common-errors
- →Debugging API 429 errors
- →Fixing authentication issues
- →Parsing GraphQL error responses
- →Troubleshooting mutation input errors
About this skill
Linear Common Errors
Overview
Quick reference for diagnosing and resolving common Linear API and SDK errors. Linear's GraphQL API returns errors in response.errors[] with extensions.type and extensions.userPresentableMessage fields. HTTP 200 responses can still contain partial errors -- always check the errors array.
Prerequisites
- Linear SDK or raw API access configured
- Access to application logs
- Understanding of GraphQL error response format
Instructions
Error Response Structure
// Linear GraphQL error shape
interface LinearGraphQLResponse {
data: Record<string, any> | null;
errors?: Array<{
message: string;
path?: string[];
extensions: {
type: string; // "authentication_error", "forbidden", "ratelimited", etc.
userPresentableMessage?: string;
};
}>;
}
// SDK throws these typed errors
import { LinearError, InvalidInputLinearError } from "@linear/sdk";
// LinearError includes: .status, .message, .type, .query, .variables
// InvalidInputLinearError extends LinearError for mutation input errors
Error 1: Authentication Failures
// extensions.type: "authentication_error"
// HTTP 401 or error in response.errors
// Diagnostic check
async function testAuth(): Promise<void> {
try {
const client = new LinearClient({ apiKey: process.env.LINEAR_API_KEY! });
const viewer = await client.viewer;
console.log(`OK: ${viewer.name} (${viewer.email})`);
} catch (error: any) {
if (error.message?.includes("Authentication")) {
console.error("API key is invalid or expired.");
console.error("Fix: Settings > Account > API > Personal API keys");
}
throw error;
}
}
Quick curl diagnostic:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { id name email } }"}' | jq .
Error 2: Rate Limiting (HTTP 429)
Linear uses the leaky bucket algorithm with two budgets:
- Request limit: 5,000 requests/hour per API key
- Complexity limit: 250,000 complexity points/hour per API key
- Max single query complexity: 10,000 points
// extensions.type: "ratelimited"
// HTTP 429 with rate limit headers
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 5): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error: any) {
const isRateLimited = error.status === 429 ||
error.message?.includes("rate") ||
error.type === "ratelimited";
if (!isRateLimited || attempt === maxRetries - 1) throw error;
const delay = 1000 * Math.pow(2, attempt) + Math.random() * 500;
console.warn(`Rate limited (attempt ${attempt + 1}), waiting ${Math.round(delay)}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error("Unreachable");
}
Check rate limit status via headers:
const resp = await fetch("https://api.linear.app/graphql", {
method: "POST",
headers: {
Authorization: process.env.LINEAR_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "{ viewer { id } }" }),
});
console.log("Requests remaining:", resp.headers.get("x-ratelimit-requests-remaining"));
console.log("Requests limit:", resp.headers.get("x-ratelimit-requests-limit"));
console.log("Requests reset:", resp.headers.get("x-ratelimit-requests-reset"));
console.log("Complexity:", resp.headers.get("x-complexity"));
Error 3: Query Complexity Too High
Each property = 0.1 pt, each object = 1 pt, connections multiply children by the first argument (default 50). Max 10,000 pts per query.
// BAD: ~12,500 complexity (250 * 50 labels)
const heavy = await client.issues({ first: 250 });
// GOOD: reduce page size and fetch relations separately
const light = await client.issues({ first: 50 });
Error 4: Entity Not Found
// extensions.type: "not_found"
// Cause: deleted, archived, wrong workspace, or insufficient permissions
try {
const issue = await client.issue("nonexistent-uuid");
} catch (error: any) {
if (error.message?.includes("Entity not found")) {
console.error("Issue may be deleted, archived, or in another workspace.");
console.error("Try: client.issues({ includeArchived: true })");
}
}
Error 5: Invalid Input on Mutations
import { InvalidInputLinearError } from "@linear/sdk";
try {
await client.createIssue({
teamId: "invalid-uuid",
title: "", // Empty title
});
} catch (error) {
if (error instanceof InvalidInputLinearError) {
console.error("Invalid input:", error.message);
// error.query and error.variables contain request details
}
}
Error 6: Null Reference on Relations
// SDK models lazy-load relations -- they can be null
const issue = await client.issue("uuid");
// BAD: crashes if unassigned
// const name = (await issue.assignee).name;
// GOOD: optional chaining
const name = (await issue.assignee)?.name ?? "Unassigned";
const projectName = (await issue.project)?.name ?? "No project";
Error 7: Webhook Signature Mismatch
// Happens when LINEAR_WEBHOOK_SECRET doesn't match the webhook config
import crypto from "crypto";
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = crypto.createHmac("sha256", secret).update(payload).digest("hex");
try {
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
} catch {
return false; // Length mismatch
}
}
Error Reference Table
| Error | extensions.type | HTTP | Cause | Fix |
|---|---|---|---|---|
| Authentication required | authentication_error | 401 | Invalid/expired key | Regenerate at Settings > API |
| Forbidden | forbidden | 403 | Missing OAuth scope | Re-authorize with correct scopes |
| Rate limited | ratelimited | 429 | Budget exceeded | Exponential backoff, reduce complexity |
| Query complexity too high | query_error | 400 | Deep nesting or large pages | Reduce first, flatten query |
| Entity not found | not_found | 200 | Deleted/archived/wrong workspace | Verify ID, try includeArchived |
| Validation error | invalid_input | 200 | Bad mutation input | Check field constraints |
| Webhook sig mismatch | N/A (local) | N/A | Wrong signing secret | Match LINEAR_WEBHOOK_SECRET |
Examples
Catch-All Error Handler
import { LinearError, InvalidInputLinearError } from "@linear/sdk";
async function handleLinearOp<T>(fn: () => Promise<T>): Promise<T> {
try {
return await fn();
} catch (error) {
if (error instanceof InvalidInputLinearError) {
console.error(`Input error: ${error.message}`);
} else if (error instanceof LinearError) {
console.error(`Linear error [${error.status}]: ${error.message}`);
if (error.status === 429) {
console.error("Rate limited — implement backoff");
}
} else {
console.error("Unexpected error:", error);
}
throw error;
}
}
Resources
When not to use it
- →When not interacting with the Linear API or SDK
- →When application logs are not accessible
Prerequisites
Limitations
- →Requires Linear SDK or raw API access
- →Requires access to application logs
- →Requires understanding of GraphQL error response format
How it compares
This skill offers specific solutions and code snippets for Linear API errors, providing a direct approach to troubleshooting compared to general API debugging.
Compared to similar skills
linear-common-errors side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| linear-common-errors (this skill) | 1 | 27d | Caution | Advanced |
| n8n-expression-syntax | 6 | 4mo | No flags | Beginner |
| claude-in-chrome-troubleshooting | 2 | 2mo | Review | Intermediate |
| openrouter-common-errors | 3 | 27d | Caution | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
n8n-expression-syntax
czlonkowski
Validate n8n expression syntax and fix common errors. Use when writing n8n expressions, using {{}} syntax, accessing $json/$node variables, troubleshooting expression errors, or working with webhook data in workflows.
claude-in-chrome-troubleshooting
trailofbits
Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.
openrouter-common-errors
jeremylongshore
Execute diagnose and fix common OpenRouter API errors. Use when troubleshooting failed requests. Trigger with phrases like 'openrouter error', 'openrouter not working', 'openrouter 401', 'openrouter 429', 'fix openrouter'.
gamma-common-errors
jeremylongshore
Debug and resolve common Gamma API errors. Use when encountering authentication failures, rate limits, generation errors, or unexpected API responses. Trigger with phrases like "gamma error", "gamma not working", "gamma API error", "gamma debug", "gamma troubleshoot".
groq-common-errors
jeremylongshore
Diagnose and fix Groq common errors and exceptions. Use when encountering Groq errors, debugging failed requests, or troubleshooting integration issues. Trigger with phrases like "groq error", "fix groq", "groq not working", "debug groq".
linear-debug-bundle
jeremylongshore
Comprehensive debugging toolkit for Linear integrations. Use when setting up logging, tracing API calls, or building debug utilities for Linear. Trigger with phrases like "debug linear integration", "linear logging", "trace linear API", "linear debugging tools", "linear troubleshooting".