{"record":{"id":"f32aa61b22e2fd00","repo":"can1357/oh-my-pi","slug":"response-errormessage-provider-error","errorCode":null,"errorMessage":"${response.errorMessage ?? \"provider error\"}","messagePattern":"\\$\\{response\\.errorMessage \\?\\? \"provider error\"\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/commit/changelog/generate.ts","lineNumber":71,"sourceCode":"\t\tis_package_changelog: isPackageChangelog,\n\t\texisting_entries: existingEntries,\n\t\tstat,\n\t\tdiff,\n\t});\n\tconst response = await retryTransientCompletion(() =>\n\t\tcompleteSimple(\n\t\t\tmodel,\n\t\t\t{\n\t\t\t\tsystemPrompt: [prompt.render(changelogSystemPrompt)],\n\t\t\t\tmessages: [{ role: \"user\", content: userContent, timestamp: Date.now() }],\n\t\t\t\ttools: [changelogTool],\n\t\t\t},\n\t\t\t{ apiKey, maxTokens: 1200, reasoning: toReasoningEffort(thinkingLevel) },\n\t\t),\n\t);\n\n\tif (response.stopReason === \"error\") {\n\t\tthrow new Error(response.errorMessage ?? \"provider error\");\n\t}\n\n\tconst parsed = parseChangelogResponse(response);\n\treturn { entries: dedupeEntries(parsed.entries) };\n}\n\nfunction parseChangelogResponse(message: AssistantMessage): ChangelogGenerationResult {\n\tconst toolCall = extractToolCall(message, \"create_changelog_entries\");\n\tif (toolCall) {\n\t\tconst parsed = validateToolCall([changelogTool], toolCall) as typeof changelogTool.parameters.infer;\n\t\treturn { entries: parsed.entries ?? {} };\n\t}\n\n\tconst text = extractTextContent(message);\n\tconst parsed = parseJsonPayload(text) as ChangelogGenerationResult;\n\treturn { entries: parsed.entries ?? {} };\n}\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/commit/changelog/generate.ts#L53-L89","documentation":"generateChangelogEntries() calls the LLM to draft changelog entries; if the response's stopReason is \"error\", the raw provider error message is rethrown as an Error (defaulting to \"provider error\" when errorMessage is absent). This propagates transport/auth/model failures from the changelog-generation call.","triggerScenarios":"The changelog LLM request completes with stopReason === \"error\" — invalid/missing apiKey, network failure, model not found, rate limit, or context overflow with maxTokens: 1200.","commonSituations":"Expired or unset provider API key; network outage; selected model unavailable; request exceeding provider rate limits during bulk commits.","solutions":["Read the embedded errorMessage — it names the provider-side cause (auth, 429, model id)","Verify the provider API key is set and valid","Retry — rate-limit and transient network errors are often temporary","Use --no-changelog or a different model to bypass changelog generation"],"exampleFix":"// before\nconst apiKey = process.env.PI_API_KEY; // undefined -> provider error\n// after\nif (!apiKey) throw new Error(\"Set PI_API_KEY before generating changelog\");","handlingStrategy":"retry","validationCode":"if (!apiKey) throw new Error(\"Changelog generation skipped: no API key configured\");","typeGuard":null,"tryCatchPattern":"try {\n  const { entries } = await generateChangelogEntries(...);\n} catch (err) {\n  logger.warn(\"Changelog generation failed\", { cause: err.message });\n  // proceed without changelog or run with --no-changelog\n}","preventionTips":["Ensure provider API keys are set and valid before running commit automation","Add bounded retries with backoff for rate-limit errors","Keep changelog prompts small (maxTokens: 1200 cap)"],"tags":["llm","provider","network","changelog"],"backgroundTag":"llm-provider-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}