{"record":{"id":"48a4e63172ef58ec","repo":"deepseek-ai/deepseek-harness","slug":"llm-pi-ai-providers-is-now-a-dict-keyed-by-provid","errorCode":null,"errorMessage":"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles","messagePattern":"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/llm/llm-pi-ai/src/config.ts","lineNumber":383,"sourceCode":"      `llm-pi-ai: provider \"${provider}\" sets maxRetries or maxRetryDelayMs, which were removed;`\n      + ' compose agent recovery with dsh-llm-retry',\n    )\n  }\n}\n\n/**\n * Validate profiles and return a detached route-keyed map suitable for\n * per-request reads. This is the one explicit resolve step, so an omitted dict\n * resolves to the empty (dormant) route set here rather than through a hidden\n * fallback, and each route's models and pi-ai provider are materialized once.\n * @param providers - configured provider profiles keyed by route.\n * @returns validated profiles in configuration order.\n */\nexport function resolveProfiles(\n  providers: Readonly<Record<string, PiAiProviderProfile>> | undefined,\n): Map<string, ResolvedPiAiProviderProfile> {\n  if (Array.isArray(providers)) {\n    throw new Error('llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles')\n  }\n  const entries = Object.entries(providers ?? {})\n  const resolved = new Map<string, ResolvedPiAiProviderProfile>()\n  for (const [provider, source] of entries) {\n    rejectRemovedFields(provider, source)\n    if (provider.length === 0) throw new Error('llm-pi-ai: provider names must be non-empty')\n    if (source.baseURL !== undefined && source.baseURL.length === 0) {\n      throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`)\n    }\n    if (source.displayName !== undefined && source.displayName.length === 0) {\n      throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`)\n    }\n    const streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS\n    if (!Number.isFinite(streamIdleTimeoutMs)\n      || streamIdleTimeoutMs <= 0\n      || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) {\n      throw new Error(\n        `llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`,","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/llm/llm-pi-ai/src/config.ts#L365-L401","documentation":"Error \"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\" thrown in deepseek-ai/deepseek-harness.","triggerScenarios":"Thrown at packages/llm/llm-pi-ai/src/config.ts:383 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rewrite providers as a dict keyed by provider route instead of an array of profiles."],"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"}