janhq/jan · error
Could not unload the model. Stop its active requests and…
Error message
Could not unload the model. Stop its active requests and try again.
What it means
Thrown by increaseCoworkContext when, for non-llamacpp providers with the model active, models.stopModel fails (result?.success falsy). Raising the context size requires unloading the model first; if stop fails the change is aborted, surfacing the backend's error message or this fallback.
Solutions
- Stop any active chats/requests using the model, wait a moment, then retry the context increase
- Manually stop the model from the provider/model list UI and start it again
- Restart the app or provider backend if the stop call keeps failing
- Check backend logs for the real stopModel error (result.error) to address the root cause
Example fix
// before
const result = await models.stopModel(modelId, providerName)
if (!result?.success) throw new Error(result?.error ?? 'Could not unload the model. Stop its active requests and try again.')
// after
const result = await models.stopModel(modelId, providerName)
if (!result?.success) {
await new Promise((r) => setTimeout(r, 1000))
const retried = await models.stopModel(modelId, providerName)
if (!retried?.success) throw new Error(retried?.error ?? 'Could not unload the model. Stop its active requests and try again.')
} Defensive patterns
Strategy: retry
Validate before calling
const active = await models.getActiveModels(providerName) if (!active.includes(modelId)) return // model not running; no stop needed
Type guard
const stopSucceeded = (r: { success?: boolean } | null | undefined): r is { success: true } =>
!!r && r.success === true Try / catch
try {
await increaseCoworkContext(modelId, providerName)
} catch (e) {
if (e.message.includes('Could not unload the model')) {
showToast('Finish active requests on this model, stop it manually, then retry.')
}
} Prevention
- Cancel active chats/streams before changing model settings
- Retry stopModel after a short delay before failing
- Surface result.error from the backend instead of only the fallback text
- Track request liveness so the UI blocks context changes while streaming
When it happens
Trigger: Calling stopModel(modelId, providerName) returns { success: false } or null — the model has in-flight requests it cannot kill, the backend is unreachable, or the stop endpoint returned an error that is empty (triggering the fallback message).
Common situations: An active chat/agent request is still streaming against the model; the provider backend hung; a race where another tab restarted the model; stale model state making the stop call target a non-running instance.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/ced10478beb7a123.
Report an issue: GitHub.
Appendix: source
Thrown at web-app/src/lib/coworkModelControls.ts:80
const setting = coworkLocalModel(provider, modelId)?.settings?.ctx_len
const value = Number(setting?.controller_props?.value)
if (setting && Number.isInteger(value) && value > 0) {
const max = await models.getModelContextLimit(modelId, providerName)
if (max !== undefined && Number.isInteger(max) && max > 0)
context = { value, max, next: nextCoworkContextSize(value, max) }
}
}
if (context?.next === undefined)
throw new Error(
'No supported context increase is available. Check the model context limit in provider settings.'
)
if (providerName === 'llamacpp') {
await models.updateModelSettings(modelId, { ctx_len: context.next })
} else if ((await models.getActiveModels(providerName)).includes(modelId)) {
const result = await models.stopModel(modelId, providerName)
if (!result?.success)
throw new Error(
result?.error ??
'Could not unload the model. Stop its active requests and try again.'
)
}
// Publish only after application succeeds. Merge into live state without
// restoring an old provider snapshot or changing the user's selection.
const state = useModelProvider.getState()
const latest = state.getProviderByName(providerName)
if (!latest) return
state.updateProvider(providerName, {
models: latest.models.map((model) =>
model.id === modelId
? ({
...model,
settings: {
...model.settings,
ctx_len: {View on GitHub (pinned to 7205d770c1)