different-ai/openwork · error · Error
Selected model is unavailable. Choose another model before s
Error message
Selected model is unavailable. Choose another model before sending.
What it means
Before sending a message, the send path validates the exact model identity this conversation will submit (session-scoped selection, falling back to the user's default model) with resolveModelAvailability(). If that model's status is 'unavailable' — e.g. the provider is disconnected, the model was removed, or the API key is missing — the send is rejected with this error instead of failing server-side.
Source
Thrown at apps/app/src/react-app/shell/session-route.tsx:1275
openSettings: handleOpenSettings,
});
},
onSendDraft: async (draft: ComposerDraft, sessionId: string): Promise<CloudMcpSubmissionResult> => {
const targetSessionId = sessionId.trim() || selectedSessionId;
if (!targetSessionId) return { outcome: "cancelled", reason: "context_changed" };
const text = (draft.resolvedText ?? draft.text).trim();
if (!text && draft.attachments.length === 0) {
return { outcome: "cancelled", reason: "context_changed" };
}
// Per-conversation model memory: a session that picked its own model
// sends with it (and its variant) instead of the global default.
const sessionModelSelection = getSessionModelSelection(targetSessionId);
const sendModel = sessionModelSelection?.model ?? local.prefs.defaultModel;
const sendVariant = sessionModelSelection ? sessionModelSelection.variant : modelVariantValue;
// Send-time validation targets the exact provider/model identity this
// conversation displays and will submit — not the global default.
if (resolveModelAvailability(sendModel ?? null).status === "unavailable") {
throw new Error("Selected model is unavailable. Choose another model before sending.");
}
return submitWithCloudMcpReadiness({
// Temporarily bypass the pre-send Cloud MCP gate: it blocks every
// message, including tasks that do not use connected services.
skipGate: true,
send: async () => {
await sendWithRevertRollback({
revertMessageId: draft.revertMessageId,
abort: () => abortSessionSafe(opencodeClient, targetSessionId, selectedWorkspaceRoot || undefined, {
source: "session.edit_resend.before_revert",
initiator: "user",
reason: "abort active run before replacing a reverted message",
}),
revert: async (messageId) => {
const reverted = await revertSession(opencodeClient, targetSessionId, messageId);
applySessionRevert(selectedWorkspaceId, reverted);
},View on GitHub (pinned to 2b7df46e8a)
Solutions
- Open the model picker for the conversation and choose an available model, then resend
- Reconnect or re-authenticate the provider that owns the model (add/fix its API key in Settings → Models/Providers)
- Clear the stale session model selection so it falls back to a valid defaultModel
- Update the app/provider catalog if the model id changed upstream
Example fix
// before useSessionModelStore.getState().setModel(sessionId, "anthropic/claude-2.1", null) // stale id // after useSessionModelStore.getState().setModel(sessionId, resolveFirstAvailableModel(), null)
Defensive patterns
Strategy: validation
Validate before calling
const availability = resolveModelAvailability(sendModel ?? null);
if (availability.status === "unavailable") {
notify(`Model ${sendModel} is unavailable; pick another.`);
return;
}
await send(); Type guard
const isModelAvailable = (m: string | null | undefined): m is string => !!m && resolveModelAvailability(m).status !== "unavailable";
Try / catch
try {
await send();
} catch (e) {
if (String(e.message).startsWith("Selected model is unavailable")) {
openModelPicker(targetSessionId);
}
} Prevention
- Prune stale session model selections when the provider catalog refreshes
- Re-validate saved defaultModel against availability on app start
- Show availability badges in the model picker so dead models are obvious
- Re-authenticate providers whose keys expired
When it happens
Trigger: Calling the send/submit handler when resolveModelAvailability(sendModel).status === 'unavailable': session model selection or defaultModel points to a provider/model that is disconnected, unauthenticated, or no longer in the model list.
Common situations: A provider API key was revoked or removed from settings; models.dev/provider catalog changed and an old model id persists in the session store; cloud inference was disabled; user switched from a local to a remote workspace whose endpoint lacks that model.
Related errors
- Use a horizontal wordmark between 1.5:1 and 8:1.
- Agent context diagnostics timeout must be between 1 ms and 3
- Invalid cloud provider sync response.
- Invalid cloud provider sync status.
- Invalid cloud provider sync status response.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/379c4d4e52a29e1e.
Report an issue: GitHub.