{"record":{"id":"d48c8622067b61f8","repo":"windmill-labs/windmill","slug":"openai-not-initialized","errorCode":null,"errorMessage":"OpenAI not initialized","messagePattern":"OpenAI not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/lib.ts","lineNumber":550,"sourceCode":"\tprivate openaiClient: OpenAI | undefined\n\tprivate anthropicClient: Anthropic | undefined\n\n\tinit(workspace: string) {\n\t\tthis.openaiClient = this.createOpenaiClient(workspace)\n\t\tthis.anthropicClient = this.createAnthropicClient(workspace)\n\t}\n\n\tcreateOpenaiClient(workspace: string): OpenAI {\n\t\treturn createOpenAIProxyClient(getAiProxyBaseURL(workspace))\n\t}\n\n\tcreateAnthropicClient(workspace: string): Anthropic {\n\t\treturn createAnthropicProxyClient(getAiProxyBaseURL(workspace))\n\t}\n\n\tgetOpenaiClient() {\n\t\tif (!this.openaiClient) {\n\t\t\tthrow new Error('OpenAI not initialized')\n\t\t}\n\t\treturn this.openaiClient\n\t}\n\n\tgetAnthropicClient() {\n\t\tif (!this.anthropicClient) {\n\t\t\tthrow new Error('Anthropic not initialized')\n\t\t}\n\t\treturn this.anthropicClient\n\t}\n}\n\nexport const workspaceAIClients = new WorkspacedAIClients()\n\nexport async function testKey({\n\tapiKey,\n\tworkspace,\n\tresourcePath,","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/lib.ts#L532-L568","documentation":"WorkspacedAIClients lazily caches a per-workspace OpenAI SDK client. getOpenaiClient() throws 'OpenAI not initialized' when the internal openaiClient field is still undefined — i.e. createOpenaiClient(workspace) was never called for the current workspace before a consumer asked for the client. It is an internal ordering guard, not an AI-provider failure.","triggerScenarios":"Calling workspaceAIClients.getOpenaiClient() (directly or via code paths in openai-responses.ts / chatLoop.ts) before any createOpenaiClient(workspace) call has populated the cache for that workspace, or after the cache was cleared/reset on workspace switch.","commonSituations":"Workspace switched in the UI without re-initializing clients; a new copilot feature calls getOpenaiClient() in a code path that runs before the manager (AIChatManager) has set up the workspace clients; hot-module-reload or test harness creating a fresh module instance without running initialization.","solutions":["Call workspaceAIClients.createOpenaiClient(workspace) with the current workspace before any use of getOpenaiClient().","Check whether the code path uses a stale workspace string after a workspace switch; re-create clients on switch.","If writing a new consumer, take the client from AIChatManager (clients.openai) instead of reaching into the singleton directly.","In tests/HMR, re-import or re-instantiate the singleton so initialization state is consistent."],"exampleFix":"// before\nconst openai = workspaceAIClients.getOpenaiClient()\n// after\nworkspaceAIClients.createOpenaiClient(workspace)\nconst openai = workspaceAIClients.getOpenaiClient()","handlingStrategy":"validation","validationCode":"function hasOpenaiClient(ws: string): boolean {\n  // createOpenaiClient returns the cached instance; call it once at setup time\n  return typeof ws === 'string' && ws.length > 0\n}","typeGuard":null,"tryCatchPattern":"try {\n  const openai = workspaceAIClients.getOpenaiClient()\n  // use openai\n} catch (e) {\n  if (e.message === 'OpenAI not initialized') {\n    workspaceAIClients.createOpenaiClient(workspace)\n  } else throw e\n}","preventionTips":["Always call createOpenaiClient(workspace) during app/workspace bootstrap before any AI feature runs.","Re-create clients on every workspace switch.","Prefer consuming clients from AIChatManager rather than the raw singleton."],"tags":["frontend","initialization","copilot","openai"],"backgroundTag":"client-not-initialized","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"}