windmill-labs/windmill · error

No model selected

Error message

No model selected

What it means

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.

Source

Thrown at frontend/src/lib/aiStore.ts:183

			// An exhausted free grant lands here — no providers, but the reason AI is off
			// is "you used it up", not "you never set it up".
			freeTier: aiConfig.free_tier
		})
	}
}

export function isWebSearchEnabledForProvider(provider: AIProvider | undefined): boolean {
	if (!provider) {
		return false
	}
	return get(copilotInfo).webSearchEnabledProviders?.[provider] ?? true
}

export function getCurrentModel(): ReasoningProviderModel {
	const model =
		get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0]
	if (!model) {
		throw new Error('No model selected')
	}
	return model
}

export function getMetadataModel(): AIProviderModel {
	const info = get(copilotInfo)
	const model = info.metadataModel ?? info.defaultModel ?? info.aiModels[0]
	if (!model) {
		throw new Error('No model selected')
	}
	return model
}

export function tryGetCurrentModel(): ReasoningProviderModel | undefined {
	return get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0]
}

export function getUserCustomPrompts(): Record<string, string> {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Configure at least one AI provider (and a default model) in instance admin AI settings, then reload the page so copilotInfo.aiModels is populated.
  2. In code that may run without a model, call tryGetCurrentModel() instead of getCurrentModel() and handle undefined.
  3. 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.
  4. If this fires during initial load, gate the calling code on copilotInfo being loaded (aiModels populated) rather than calling synchronously on mount.

Example fix

// before
const model = getCurrentModel()
// after
const model = tryGetCurrentModel()
if (!model) {
  toast.info('No AI model is configured. Add a provider in admin settings.')
  return
}
Defensive patterns

Strategy: type-guard

Validate before calling

const info = get(copilotInfo)
if (!get(copilotSessionModel) && !info.defaultModel && info.aiModels.length === 0) {
  // no model available — surface config UI or bail out before calling getCurrentModel()
}

Type guard

function hasCurrentModel(): boolean {
  const info = get(copilotInfo)
  return !!(get(copilotSessionModel) ?? info.defaultModel ?? info.aiModels[0])
}

Try / catch

try {
  const model = getCurrentModel()
  // use model
} catch {
  toast.info('No AI model is configured for this workspace.')
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/7f389ff76385ea54. Report an issue: GitHub.