{"record":{"id":"ac632fb158a425d0","repo":"can1357/oh-my-pi","slug":"completion-has-no-api-key-for-formatmodelstrin","errorCode":null,"errorMessage":"completion() has no API key for ${formatModelString(model)}. Configure credentials for this provider or choose another tier.","messagePattern":"completion\\(\\) has no API key for (.+?)\\. Configure credentials for this provider or choose another tier\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/eval/completion-bridge.ts","lineNumber":129,"sourceCode":"\tconst parsed = completionArgsSchema(args);\n\tif (parsed instanceof type.errors) {\n\t\tthrow new ToolError(`completion() received invalid arguments: ${parsed.summary}`);\n\t}\n\tconst { prompt, model: modelTier, system, schema } = parsed;\n\t// Apply default value for model if not provided\n\tconst finalTier: CompletionTier = modelTier ?? \"default\";\n\n\tconst model = resolveTierModel(finalTier, options.session);\n\tif (!model) {\n\t\tthrow new ToolError(\n\t\t\t`completion() could not resolve a model for the \"${finalTier}\" tier. Configure modelRoles.${finalTier === \"default\" ? \"default\" : finalTier} or ensure a provider is available.`,\n\t\t);\n\t}\n\n\tconst registry = options.session.modelRegistry;\n\tconst apiKey = await registry?.getApiKey(model);\n\tif (!registry || !apiKey) {\n\t\tthrow new ToolError(\n\t\t\t`completion() has no API key for ${formatModelString(model)}. Configure credentials for this provider or choose another tier.`,\n\t\t);\n\t}\n\n\tconst tools: Tool[] | undefined = schema\n\t\t? [\n\t\t\t\t{\n\t\t\t\t\tname: STRUCTURED_TOOL_NAME,\n\t\t\t\t\tdescription: \"Return your answer by calling this tool with the requested structured fields.\",\n\t\t\t\t\tparameters: schema,\n\t\t\t\t\tstrict: false,\n\t\t\t\t},\n\t\t\t]\n\t\t: undefined;\n\n\tconst telemetry = resolveTelemetry(options.session.getTelemetry?.(), options.session.getSessionId?.() ?? undefined);\n\n\t// Some providers (notably openai-codex) require a non-empty `instructions`","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/eval/completion-bridge.ts#L111-L147","documentation":"After resolving a model for the requested tier, the bridge fetches its API key through the session's model registry (`registry.getApiKey(model)`). This ToolError is thrown when there is no model registry on the session or the resolver returns no key, meaning credentials for the resolved provider are missing. It guards the actual `completeSimple` request from failing with an opaque provider auth error.","triggerScenarios":"`completion(prompt, ...)` resolves a valid model (e.g. `anthropic/claude-...`) but `session.modelRegistry` is absent, or `getApiKey(model)` returns undefined because no API key/env var/OAuth credential is configured for that provider.","commonSituations":"Anthropic or OpenAI key not set in env or auth config; key configured for one provider but the tier's role points at another; running evals in a container where the credential file/env isn't mounted; model registry not attached to the eval ToolSession.","solutions":["Configure credentials for the resolved provider (API key env var, auth config, or provider login) and retry.","Choose a different tier whose provider you do have credentials for (`completion(prompt, { model: \"smol\" })`).","Verify the env var the provider expects (e.g. ANTHROPIC_API_KEY / OPENAI_API_KEY) is present in the process running the eval.","If embedding the bridge in your own session, ensure `session.modelRegistry` is set with a working key resolver."],"exampleFix":"// before\nexport ANTHROPIC_API_KEY=  # unset\nconst out = await completion(\"classify this\");\n// after\nexport ANTHROPIC_API_KEY=sk-ant-...\nconst out = await completion(\"classify this\");","handlingStrategy":"validation","validationCode":"const registry = session.modelRegistry;\nconst model = /* resolve tier model as in the bridge */;\nconst apiKey = model && registry ? await registry.getApiKey(model) : undefined;\nif (!registry || !apiKey) throw new Error(`No API key for ${model?.id ?? \"resolved model\"}`);","typeGuard":null,"tryCatchPattern":"try {\n  const out = await completion(prompt);\n} catch (e) {\n  if (String(e).includes(\"no API key\")) {\n    // guide user to set provider credentials or switch tier\n  } else throw e;\n}","preventionTips":["Set the provider API key env vars in the environment running evals (including CI secrets).","Point tiers at providers you actually have credentials for.","Smoke-test one completion() call at eval startup to fail fast on missing credentials."],"tags":["authentication","api-key","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}