musistudio/claude-code-router · error · Error

Kimi CLI credential was not found or is expired.

Error message

Kimi CLI credential was not found or is expired.

What it means

importKimiProvider could not obtain a usable credential: either no API key is configured and OAuth produced no access token, or the OAuth token exists but is considered expired by kimiAccessTokenExpired. Import is aborted so the agent never starts with a dead credential.

Source

Thrown at packages/core/src/agents/local-providers/kimi.ts:144

    sourceFile: auth?.sourceFile ?? configured.sourceFile,
    status: "locked"
  };
}

export async function importKimiProvider(
  candidate: LocalAgentProviderCandidate,
  providerNames: string[]
): Promise<LocalAgentProviderImportResult> {
  const configured = readKimiConfiguredProviders().find((item) => item.candidateId === candidate.id);
  if (!configured) {
    throw new Error("Kimi CLI provider configuration was not found.");
  }
  const usesOauth = Boolean(configured.oauthKey && !configured.apiKey);
  const oauthReference = kimiOauthReference(configured);
  const auth = usesOauth ? await resolveKimiAuth(oauthReference) : undefined;
  const token = configured.apiKey || auth?.accessToken;
  if (!token || (auth && kimiAccessTokenExpired(auth))) {
    throw new Error("Kimi CLI credential was not found or is expired.");
  }
  const nextCandidate: LocalAgentProviderCandidate = {
    ...candidate,
    modelDisplayNames: configured.modelDisplayNames,
    modelMetadata: configured.modelMetadata,
    models: configured.models,
    protocol: configured.protocol
  };
  const provider = providerPayload(
    nextCandidate,
    uniqueProviderName(providerNames, configured.name),
    configured.baseUrl,
    kimiProviderAccountConfig(configured.baseUrl)
  );
  const authSuffix = usesOauth ? "kimi-cli-oauth" : "kimi-cli-api-key";
  return {
    candidate: nextCandidate,
    provider,

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Run kimi login (or set the API key in config) to establish a fresh credential
  2. If OAuth, confirm the stored token set refreshes successfully — if refresh also 401s, re-login is required
  3. Check system clock/NTP sync
  4. Verify the credentials file was not deleted or made unreadable
Defensive patterns

Strategy: validation

Validate before calling

const auth = await resolveKimiAuth(ref).catch(() => undefined);
const hasCredential = Boolean(configured.apiKey || auth?.accessToken);
const fresh = !auth || !kimiAccessTokenExpired(auth);
if (!hasCredential || !fresh) {
  await kimiLogin(); // refresh before importing
}

Type guard

function hasUsableKimiCredential(cfg: KimiConfig, auth?: KimiTokenSet): boolean {
  return Boolean(cfg.apiKey || (auth?.accessToken && !kimiAccessTokenExpired(auth)));
}

Try / catch

catch (e) {
  if (e instanceof Error && e.message === 'Kimi CLI credential was not found or is expired.') {
    await kimiLogin(); // then retry import once
  }
}

Prevention

When it happens

Trigger: configured.apiKey is empty, resolveKimiAuth returned undefined/failed to yield an accessToken, or the resolved auth's expiry check (kimiAccessTokenExpired) is true and refresh did not produce a fresh token.

Common situations: User never logged in and set no KIMI_API_KEY; long-lived session where the refresh token also expired; clock skew making a valid token appear expired; credentials file removed.

Related errors


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