{"record":{"id":"1152420547ac6c39","repo":"deepseek-ai/deepseek-harness","slug":"missing-credential-115242","errorCode":"MISSING_CREDENTIAL","errorMessage":"llm-pi-ai: no credential for provider route \"${provider}\"; its profile resolves ${ref}, which is not set — store ${ref} through the credentials service (the web Models page writes it) or export it, and remove apiKeyEnv only if this provider should authenticate from pi-ai's own environment discovery","messagePattern":"llm-pi-ai: no credential for provider route \"(.+?)\"; its profile resolves (.+?), which is not set — store (.+?) through the credentials service \\(the web Models page writes it\\) or export it, and remove apiKeyEnv only if this provider should authenticate from pi-ai's own environment discovery","errorType":"exception","errorClass":"LlmError","httpStatus":null,"severity":"error","filePath":"packages/llm/llm-pi-ai/src/index.ts","lineNumber":183,"sourceCode":"\n  const resolveApiKey = async (\n    provider: string,\n    profile: ResolvedPiAiProviderProfile,\n  ): Promise<string | undefined> => {\n    const ref = profile.apiKeyEnv\n    // Only a profile that names no credential at all defers to pi-ai's\n    // provider-native discovery. Once one is named, a miss must fail loud:\n    // handing pi-ai `undefined` would let it pick up an unrelated ambient key\n    // (OPENAI_API_KEY and friends), billing another tenant for a request the\n    // deployment meant to authenticate differently.\n    if (ref === undefined) return undefined\n    const credentials = ctx.get('credentials')\n    const hit = credentials !== undefined\n      ? (await credentials.resolve(ref))?.value\n      // Without the seam the environment is the whole credential plane.\n      : launchEnvironmentOf(ctx).get(ref)?.value\n    if (hit !== undefined && hit.length > 0) return assertUsableApiKey(hit, 'llm-pi-ai', ref)\n    throw new LlmError(\n      `llm-pi-ai: no credential for provider route \"${provider}\"; its profile resolves ${ref}, which is not`\n      + ` set — store ${ref} through the credentials service (the web Models page writes it) or export it,`\n      + ' and remove apiKeyEnv only if this provider should authenticate from pi-ai\\'s own environment discovery',\n      'MISSING_CREDENTIAL',\n    )\n  }\n\n  // One store and one ambient context for the whole plugin instance: both read\n  // through `ctx` per call, so they stay correct across the collection rebuilds\n  // a configuration change causes, and a sign-in survives one.\n  const auth = { credentials: credentialStoreFrom(ctx), authContext: authContextFrom(ctx) }\n  const adapter = new PiAiAdapter({\n    profiles,\n    resolveApiKey,\n    auth,\n    resolveAttachments: () => ctx.get('attachments'),\n    onReplayDegrade: ({ provider, model, reason }) => {\n      ctx.logger.warn(","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/llm/llm-pi-ai/src/index.ts#L165-L201","documentation":"Error \"llm-pi-ai: no credential for provider route \"${provider}\"; its profile resolves ${ref}, which is not set — store ${ref} through the credentials service (the web Models page writes it) or export it, and remove apiKeyEnv only if this provider should authenticate from pi-ai's own environment discovery\" thrown in deepseek-ai/deepseek-harness.","triggerScenarios":"Thrown at packages/llm/llm-pi-ai/src/index.ts:183 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Store the referenced key through the credentials service (the web Models page writes it) or export it; remove apiKeyEnv only if the provider should authenticate from pi-ai's own environment discovery."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}