{"record":{"id":"7f389ff76385ea54","repo":"windmill-labs/windmill","slug":"no-model-selected","errorCode":null,"errorMessage":"No model selected","messagePattern":"No model selected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/aiStore.ts","lineNumber":183,"sourceCode":"\t\t\t// An exhausted free grant lands here — no providers, but the reason AI is off\n\t\t\t// is \"you used it up\", not \"you never set it up\".\n\t\t\tfreeTier: aiConfig.free_tier\n\t\t})\n\t}\n}\n\nexport function isWebSearchEnabledForProvider(provider: AIProvider | undefined): boolean {\n\tif (!provider) {\n\t\treturn false\n\t}\n\treturn get(copilotInfo).webSearchEnabledProviders?.[provider] ?? true\n}\n\nexport function getCurrentModel(): ReasoningProviderModel {\n\tconst model =\n\t\tget(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0]\n\tif (!model) {\n\t\tthrow new Error('No model selected')\n\t}\n\treturn model\n}\n\nexport function getMetadataModel(): AIProviderModel {\n\tconst info = get(copilotInfo)\n\tconst model = info.metadataModel ?? info.defaultModel ?? info.aiModels[0]\n\tif (!model) {\n\t\tthrow new Error('No model selected')\n\t}\n\treturn model\n}\n\nexport function tryGetCurrentModel(): ReasoningProviderModel | undefined {\n\treturn get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0]\n}\n\nexport function getUserCustomPrompts(): Record<string, string> {","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/aiStore.ts#L165-L201","documentation":"getCurrentModel() in aiStore.ts resolves the active AI model from the session-selected model (copilotSessionModel), the instance defaultModel, or the first entry of aiModels. If all three are absent — i.e. the workspace/instance has no AI provider models configured and the user has not picked one — it throws 'No model selected' instead of returning undefined. The non-throwing sibling tryGetCurrentModel() exists for code that can proceed without a model.","triggerScenarios":"Calling any getter that reaches getCurrentModel (provider, currentModel, modelProvider, webSearch, model) while copilotSessionModel is unset, copilotInfo.defaultModel is undefined, and copilotInfo.aiModels is empty — e.g. before copilotInfo has loaded or on an instance/workspace with no AI providers configured.","commonSituations":"Self-hosted instances where no OpenAI/Anthropic/Azure etc. provider is configured in admin AI settings; a user opening the AI chat before the /ai config request completes; an exhausted free tier leaving aiModels empty; a stale frontend bundle where defaultModel disappeared from the server response.","solutions":["Configure at least one AI provider (and a default model) in instance admin AI settings, then reload the page so copilotInfo.aiModels is populated.","In code that may run without a model, call tryGetCurrentModel() instead of getCurrentModel() and handle undefined.","Check that the user did not clear the model picker: the session selection is stored in copilotSessionModel — pick a model in the chat UI before triggering actions that need one.","If this fires during initial load, gate the calling code on copilotInfo being loaded (aiModels populated) rather than calling synchronously on mount."],"exampleFix":"// before\nconst model = getCurrentModel()\n// after\nconst model = tryGetCurrentModel()\nif (!model) {\n  toast.info('No AI model is configured. Add a provider in admin settings.')\n  return\n}","handlingStrategy":"type-guard","validationCode":"const info = get(copilotInfo)\nif (!get(copilotSessionModel) && !info.defaultModel && info.aiModels.length === 0) {\n  // no model available — surface config UI or bail out before calling getCurrentModel()\n}","typeGuard":"function hasCurrentModel(): boolean {\n  const info = get(copilotInfo)\n  return !!(get(copilotSessionModel) ?? info.defaultModel ?? info.aiModels[0])\n}","tryCatchPattern":"try {\n  const model = getCurrentModel()\n  // use model\n} catch {\n  toast.info('No AI model is configured for this workspace.')\n}","preventionTips":["Prefer tryGetCurrentModel() whenever the model is optional in your code path.","Configure a default model in instance admin AI settings before enabling AI features.","Gate AI-dependent UI on copilotInfo being loaded (non-empty aiModels)."],"tags":["frontend","ai","configuration","svelte-store"],"backgroundTag":"missing-ai-provider-config","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"}