can1357/oh-my-pi · error · ToolError
completion() returned no text output.
Error message
completion() returned no text output.
What it means
In the non-structured path (no `schema`), the bridge returns `extractTextContent(response)` as the result. This ToolError is thrown when that yields nothing — the model finished (successfully, not aborted or errored) but produced no text content blocks (e.g. only tool calls or empty content).
Source
Thrown at packages/coding-agent/src/eval/completion-bridge.ts:198
let resultText: string;
if (schema) {
const call = extractToolCall(response, STRUCTURED_TOOL_NAME);
let value: unknown;
if (call) {
value = call.arguments;
} else {
const text = extractTextContent(response);
if (!text) throw new ToolError("completion() returned no structured response.");
try {
value = parseJsonPayload(text);
} catch {
throw new ToolError("completion() did not return a structured response matching the schema.");
}
}
resultText = JSON.stringify(value);
} else {
resultText = extractTextContent(response);
if (!resultText) throw new ToolError("completion() returned no text output.");
}
options.emitStatus?.({
op: "completion",
model: formatModelString(model),
tier: finalTier,
chars: resultText.length,
});
return {
text: resultText,
details: { model: formatModelString(model), tier: finalTier, structured: Boolean(schema) },
};
}
View on GitHub (pinned to 9690622007)
Solutions
- Retry — degenerate finishes are usually transient.
- Pass a system prompt that instructs the model to answer in plain text (the `system` option).
- Use a stronger/different tier or model that reliably emits text.
- Shorten or reword the prompt; very short prompts can trigger empty finishes on small models.
Example fix
// before
const t = (await completion("hi")).text; // can throw on empty output
// after
const t = (await completion("hi", { system: "Always answer in plain text." })).text; Defensive patterns
Strategy: retry
Try / catch
let r;
try {
r = await completion(prompt);
} catch (e) {
if (String(e).includes("no text output")) r = await completion(prompt, { system: "Always answer in plain text." });
else throw e;
} Prevention
- Always pass a system prompt instructing plain-text answers.
- Avoid tiny models for one-shot text completions.
- Retry once on empty-output errors before failing the cell.
When it happens
Trigger: `completion(prompt)` where the response's stop reason is normal (stop/end_turn) but the message contains no text blocks — content is empty, contains only tool_use/thinking blocks, or text blocks are empty strings.
Common situations: Model ends immediately with a tool call despite no tools being offered (rare provider quirk); response consisting solely of reasoning blocks on a thinking model; safety filter stripping the content; degenerate finish on a tiny model.
Related errors
- completion() returned no structured response.
- No response returned by agent creation architect.
- Devin API error: response body is empty
- Devin auth error: GetUserJwt returned an empty user JWT
- Devin AssignModel error: response carried no assignment JWT
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/04880710168e7ad1.
Report an issue: GitHub.