{"record":{"id":"fcb34989dc93c03c","repo":"abi/screenshot-to-code","slug":"generation-finished-without-producing-any-output","errorCode":null,"errorMessage":"Generation finished without producing any output.","messagePattern":"Generation finished without producing any output\\.","errorType":"exception","errorClass":"EmptyOutputError","httpStatus":null,"severity":"error","filePath":"backend/agent/engine.py","lineNumber":357,"sourceCode":"            should_generate_images=self.should_generate_images,\n            openai_api_key=self.openai_api_key,\n            openai_base_url=self.openai_base_url,\n            anthropic_api_key=self.anthropic_api_key,\n            gemini_api_key=self.gemini_api_key,\n            replicate_api_key=self.replicate_api_key,\n            # Only advertise extraction when the request actually contains a\n            # still image the runtime can crop. In particular, Gemini videos\n            # share the image_url message shape but are not valid extractor\n            # inputs.\n            should_extract_assets=(\n                self.should_extract_assets and bool(self.tool_runtime.input_images)\n            ),\n            recorder=self.recorder,\n        )\n        try:\n            result = await self._run_with_session(session)\n            if not result:\n                raise EmptyOutputError()\n            if self.recorder is not None:\n                await self.recorder.record_run_end(\"completed\", final_html=result)\n            return result\n        # BaseException so cancellation (client disconnect) still finalizes\n        # the run record instead of leaving it stuck at \"running\".\n        except BaseException as exc:\n            if self.recorder is not None:\n                await self.recorder.record_run_end(\n                    \"failed\",\n                    error=\"\".join(\n                        traceback.format_exception_only(type(exc), exc)\n                    ).strip(),\n                )\n            raise\n        finally:\n            await session.close()\n\n    async def _finalize_response(self, assistant_text: str) -> str:","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/backend/agent/engine.py#L339-L375","documentation":"EmptyOutputError is raised in Agent.run when _run_with_session returns a falsy result (empty/None assistant text) after the whole run completes 'successfully'. It exists so a run that yields no code does not get recorded as a valid completion; the recorder marks the run 'failed' with this error.","triggerScenarios":"The provider session finalizes but the accumulated final HTML/text is empty: the model returned only whitespace, all content arrived through paths that never populated the result, or the final turn's text was empty after tool stripping.","commonSituations":"Model responds purely with tool calls and no closing text, upstream API returned empty content in the final message, or streaming was cancelled near the end leaving result unpopulated.","solutions":["Retry the generation: transient empty completions are the most common cause.","Switch models — some models are more prone to ending without a final text turn.","Inspect the recorded run log to see whether the final turn had tool calls only.","If it recurs on one prompt, rephrase so the model must answer with code in its final message."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        return await engine.run(model, messages)\n    except EmptyOutputError:\n        if attempt == 1:\n            raise","preventionTips":["Treat empty completions as transient: one automatic retry removes most occurrences.","Prompt the model to end with a final code/answer message rather than only tool calls.","Record runs (recorder) so empty-output events are diagnosable after the fact."],"tags":["agent","empty-output","llm","engine"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}