musistudio/claude-code-router · error · Error

${candidate.detail || "Local agent login is not importable."

Error message

${candidate.detail || "Local agent login is not importable."}

What it means

The candidate exists but has importable=false; the thrown message is the candidate's detail text, or the generic 'Local agent login is not importable.' when no detail is set.

Source

Thrown at packages/core/src/agents/local-providers/service.ts:39

export function getLocalAgentProviderCandidates(): LocalAgentProviderCandidate[] {
  return [
    codexCandidate(),
    claudeCodeCandidate(),
    grokCandidate(),
    ...kimiCandidates(),
    ...opencodeCandidates(),
    zcodeCandidate()
  ].filter((candidate) => candidate.status !== "missing");
}

export async function importLocalAgentProvider(request: LocalAgentProviderImportRequest): Promise<LocalAgentProviderImportResult> {
  const candidate = getLocalAgentProviderCandidates().find((item) => item.id === request.id);
  if (!candidate) {
    throw new Error("Local agent provider was not found.");
  }
  if (!candidate.importable) {
    throw new Error(candidate.detail || "Local agent login is not importable.");
  }

  if (candidate.kind === "codex") {
    return importCodexProvider(candidate, request.providerNames ?? []);
  }
  if (candidate.kind === "claude-code") {
    return importClaudeCodeProvider(candidate, request.providerNames ?? []);
  }
  if (candidate.kind === "grok") {
    return importGrokProvider(candidate, request.providerNames ?? []);
  }
  if (candidate.kind === "kimi") {
    return importKimiProvider(candidate, request.providerNames ?? []);
  }
  if (candidate.kind === "opencode") {
    return importOpenCodeProvider(candidate, request.providerNames ?? []);
  }
  return importZcodeProvider(candidate, request.providerNames ?? []);

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Follow candidate.detail (usually: run the CLI and log in, e.g. `claude login`, `codex login`).
  2. Re-run candidate detection to refresh the detail message.
  3. Fix permissions on the CLI's auth/config files.
Defensive patterns

Strategy: validation

Validate before calling

if (!candidate.importable) showDetail(candidate.detail);

Type guard

function isImportable(c: LocalAgentProviderCandidate): boolean { return c.importable === true; }

Try / catch

catch (e) { if ((e as Error).message.includes('not importable')) surfaceLoginHint(candidate); }

Prevention

When it happens

Trigger: Importing a candidate whose detection marked it non-importable — e.g. CLI installed but not logged in, or login file unreadable.

Common situations: User installed the CLI but never authenticated; auth file corrupted or permissions changed.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/a9ebb9487efc48e1. Report an issue: GitHub.