Claude-skill-registry linear-common-errors

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/linear-common-errors" ~/.claude/skills/majiayu000-claude-skill-registry-linear-common-errors && rm -rf "$T"
manifest: skills/data/linear-common-errors/SKILL.md
source content

Linear Common Errors

Overview

Quick reference for diagnosing and resolving common Linear API errors.

Prerequisites

  • Linear SDK or API access configured
  • Access to application logs
  • Understanding of HTTP status codes

Error Categories

Authentication Errors (401/403)

Invalid API Key

Error: Authentication required
Code: UNAUTHENTICATED

Causes:

  • API key is invalid, expired, or revoked
  • Key format is incorrect (should start with
    lin_api_
    )
  • Environment variable not loaded

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);
}

Permission Denied

Error: You don't have permission to access this resource
Code: FORBIDDEN

Causes:

  • API key doesn't have required scope
  • User not a member of the team/organization
  • Resource belongs to different workspace

Solutions:

  • Check API key permissions in Linear Settings > API
  • Verify team membership
  • Regenerate key with correct permissions

Rate Limiting Errors (429)

Error: Rate limit exceeded
Code: RATE_LIMITED
Headers: X-RateLimit-Remaining: 0, Retry-After: 60

Causes:

  • Too many requests in time window
  • Burst of requests without throttling

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");
}

Validation Errors (400)

Error: Variable "$input" got invalid value
Code: BAD_USER_INPUT

Common Validation Failures:

FieldErrorFix
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);
}

GraphQL Errors

Error: Cannot query field "nonExistent" on type "Issue"
Code: GRAPHQL_VALIDATION_FAILED

Causes:

  • Field name typo
  • Querying deprecated field
  • SDK version mismatch with API

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 } } }"}'

Network Errors

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);
}

Diagnostic Commands

Test API Connection

curl -s -H "Authorization: $LINEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ viewer { name email } }"}' \
  https://api.linear.app/graphql | jq

Check Rate Limit Status

curl -I -H "Authorization: $LINEAR_API_KEY" \
  https://api.linear.app/graphql
# Look for: X-RateLimit-Limit, X-RateLimit-Remaining

Validate Webhook Signature

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)
  );
}

Error Handling Pattern

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;
  }
}

Resources

Next Steps

Set up comprehensive debugging with

linear-debug-bundle
.