{"record":{"id":"3265aa31022e0406","repo":"windmill-labs/windmill","slug":"ai-response-was-empty","errorCode":null,"errorMessage":"AI response was empty","messagePattern":"AI response was empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts","lineNumber":2829,"sourceCode":"\t\t\tconst params = {\n\t\t\t\tmessages,\n\t\t\t\tabortController: this.inlineAbortController,\n\t\t\t\tcallbacks: {\n\t\t\t\t\tonNewToken: (token: string) => {\n\t\t\t\t\t\treply += token\n\t\t\t\t\t},\n\t\t\t\t\tonMessageEnd: () => {},\n\t\t\t\t\tsetToolStatus: () => {},\n\t\t\t\t\tremoveToolStatus: () => {}\n\t\t\t\t},\n\t\t\t\tsystemMessage\n\t\t\t}\n\n\t\t\tawait this.chatRequest({ ...params })\n\n\t\t\t// Validate we received a response\n\t\t\tif (!reply.trim()) {\n\t\t\t\tthrow new Error('AI response was empty')\n\t\t\t}\n\n\t\t\t// Try to extract new code from response\n\t\t\tconst newCodeMatch = reply.match(/<new_code>([\\s\\S]*?)<\\/new_code>/i)\n\t\t\tif (newCodeMatch && newCodeMatch[1]) {\n\t\t\t\tconst code = newCodeMatch[1].trim()\n\t\t\t\tif (!code) {\n\t\t\t\t\tthrow new Error('AI response contained empty code block')\n\t\t\t\t}\n\t\t\t\treturn code\n\t\t\t}\n\n\t\t\t// Fallback: try to take everything after the last <new_code> tag\n\t\t\tconst lastNewCodeMatch = reply.match(/<new_code>([\\s\\S]*)/i)\n\t\t\tif (lastNewCodeMatch && lastNewCodeMatch[1]) {\n\t\t\t\tconst code = lastNewCodeMatch[1].trim().replace(/```/g, '')\n\t\t\t\tif (!code) {\n\t\t\t\t\tthrow new Error('AI response contained empty code block')","sourceCodeStart":2811,"sourceCodeEnd":2847,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts#L2811-L2847","documentation":"AIChatManager.sendInlineRequest streams the model's reply via the onNewToken callback accumulating into `reply`. After chatRequest resolves, it validates that some non-whitespace text was received. If the stream produced nothing (empty completion), this error is thrown to signal that the inline code-edit request got no usable AI output.","triggerScenarios":"Calling sendInlineRequest and the LLM completion finishes with zero tokens: the backend returns an empty completion, the model is misconfigured/unavailable and silently returns nothing, or all streamed tokens are whitespace.","commonSituations":"Model provider outage or rate limit swallowed upstream, an AI model configured in workspace settings that returns empty responses, prompt so large the provider truncates to nothing, or a proxy/gateway returning 200 with an empty body.","solutions":["Retry the inline request; transient provider issues often cause empty completions.","Check the workspace AI provider/model configuration (API key, base URL, model name) and test it.","Inspect the browser console for the 'chatRequest error' log emitted just before the throw to find the upstream cause.","Reduce prompt size (smaller selection/context) and resend."],"exampleFix":"// before\nconst code = await manager.sendInlineRequest(instructions, selected, selection)\n// after\nlet code\ntry {\n  code = await manager.sendInlineRequest(instructions, selected, selection)\n} catch (e) {\n  if (e.message === 'AI response was empty') {\n    notify('AI returned no output — please retry')\n    return\n  }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const code = await manager.sendInlineRequest(instr, sel, selection)\n} catch (e) {\n  if (e.message === 'AI response was empty') { retryOrNotify(); return }\n  throw e\n}","preventionTips":["Keep the AI provider configuration (key, model, base URL) valid and tested.","Monitor backend/provider errors instead of assuming 200 means content.","Retry empty completions automatically once before surfacing to the user."],"tags":["ai","empty-response","streaming","copilot"],"backgroundTag":"llm-empty-response","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}