{"record":{"id":"7e290512086e44b7","repo":"can1357/oh-my-pi","slug":"empty-model-response","errorCode":null,"errorMessage":"Empty model response","messagePattern":"Empty model response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/commit/conventional/inference.ts","lineNumber":133,"sourceCode":"\t\t\t\tthis.#onProgress?.(request.progressLabel);\n\t\t\t\tconst timeout = AbortSignal.timeout(120_000);\n\t\t\t\tconst signal = this.#signal ? AbortSignal.any([this.#signal, timeout]) : timeout;\n\t\t\t\tconst message = await completeSimple(\n\t\t\t\t\ttarget.model,\n\t\t\t\t\t{\n\t\t\t\t\t\tsystemPrompt: request.systemPrompt.trim() ? [request.systemPrompt] : undefined,\n\t\t\t\t\t\tmessages: [{ role: \"user\", content: request.userPrompt, timestamp: Date.now() }],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tapiKey: target.apiKey,\n\t\t\t\t\t\tmaxTokens: 16_384,\n\t\t\t\t\t\treasoning,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tresponseText = extractAssistantText(message);\n\t\t\t\tif (message.stopReason === \"error\") throw new Error(message.errorMessage ?? \"Provider error\");\n\t\t\t\tif (!responseText.trim()) throw new Error(\"Empty model response\");\n\t\t\t\tconst raw = { text: responseText, stopReason: message.stopReason };\n\t\t\t\tconst parsed = parse(raw);\n\t\t\t\tif (request.cacheable !== false) {\n\t\t\t\t\tthis.#cache?.put({\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmodel: modelKey,\n\t\t\t\t\t\toperation: request.operation,\n\t\t\t\t\t\trequest: requestJson,\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\ttext: responseText,\n\t\t\t\t\t\t\tstopReason: message.stopReason,\n\t\t\t\t\t\t\tcostUsd: message.usage.cost.total,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.#cache?.recordUsage(modelKey, request.operation, message.usage);\n\t\t\t\treturn parsed;\n\t\t\t} catch (error) {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/commit/conventional/inference.ts#L115-L151","documentation":"The conventional-commit inference pipeline sends a prompt to the LLM and extracts the assistant reply with extractAssistantText. If the message returned by the provider has an empty or whitespace-only text payload (and stopReason is not 'error'), this error is thrown because there is nothing to parse into a commit message/analysis.","triggerScenarios":"Calling complete() when the model returns an empty assistant message: provider truncation, the model emitted only reasoning/thinking content with no final text, a content filter stripped the response, or the provider returned an empty choice for the configured commit model.","commonSituations":"Misconfigured commit model (e.g. a reasoning-only or non-chat model), provider outage or degraded routing, max_tokens set too low so the model never produces output, or an API tier that silently returns empty completions.","solutions":["Retry the generation; transient provider issues often cause empty responses","Switch the commit model to a standard chat/instruct model via the model override settings","Check the provider dashboard/status for outages and verify the API key has quota","If using a reasoning model, verify thinking configuration allows final text output"],"exampleFix":"// before: empty text bubbles up as 'Empty model response'\nconst msg = await complete(prompt);\n// after: validate before parsing and retry once\nlet msg = await complete(prompt);\nif (!extractAssistantText(msg).trim()) msg = await complete(prompt);","handlingStrategy":"retry","validationCode":"const text = extractAssistantText(message);\nif (!text || !text.trim()) { /* skip parse, retry */ }","typeGuard":"function hasModelText(m: { text: string }): boolean {\n  return typeof m.text === \"string\" && m.text.trim().length > 0;\n}","tryCatchPattern":"try {\n  const msg = await inference.complete(prompt);\n} catch (err) {\n  if (err instanceof Error && err.message === \"Empty model response\") {\n    // retry once, then fall back to a manual commit message\n  }\n  throw err;\n}","preventionTips":["Use a chat/instruct model for commit generation, not a reasoning-only model","Retry transient empty responses before surfacing an error","Monitor provider status/quota when empty responses cluster in time"],"tags":["llm","empty-response","provider"],"backgroundTag":"empty-model-response","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}