janhq/jan · error · Error
model-errors:createModelFailed
Error message
model-errors:createModelFailed
What it means
Thrown when `this.createModelOrAbort(...)` rejects with a non-AbortError during message send. The catch block preserves AbortError identity (user pressed Stop) but wraps every other failure through i18n key `model-errors:createModelFailed` with `describeEngineError(error)` as the reason. This is the umbrella error for any model-load/creation failure across all providers.
Source
Thrown at web-app/src/lib/custom-chat-transport.ts:1210
updatedProvider ?? provider,
mergedParams,
providerId,
options.abortSignal
)
useAppState.getState().updateLoadingModel(false)
useAppState.getState().updateThreadLoadingModel(threadId, false)
useAppState.getState().updateModelLoadProgress(undefined)
useAppState.getState().updateThreadModelLoadProgress(threadId, undefined)
} catch (error) {
useAppState.getState().updateLoadingModel(false)
useAppState.getState().updateThreadLoadingModel(threadId, false)
useAppState.getState().updateModelLoadProgress(undefined)
useAppState.getState().updateThreadModelLoadProgress(threadId, undefined)
console.error('Failed to create model:', error)
// Preserve AbortError identity so callers/UI can tell a user-initiated
// Stop from an actual model-load failure.
if (error instanceof Error && error.name === 'AbortError') throw error
throw new Error(
i18n.t('model-errors:createModelFailed', {
reason: describeEngineError(error),
})
)
}
await this.refreshTools(options.abortSignal)
// Split assistant turns that place text after tool calls into separate
// messages. Required by the Claude API (tool_use / tool_result pairing) and
// it keeps the prompt prefix byte-identical across turns so llama.cpp reuses
// the KV cache. See `splitAssistantToolWaves`.
const messagesToConvert = splitAssistantToolWaves(options.messages)
const inferenceParams = this.getActiveInferenceParams()
const selectedModel = useModelProvider.getState().selectedModel
View on GitHub (pinned to fad3f12a14)
Solutions
- Read the `reason` in the surfaced message and the console — `describeEngineError` extracts the underlying engine message.
- For local models: reduce context length / GPU layers, free memory, or use a smaller quantization.
- For remote providers: verify the API key and base URL in provider settings.
- For GGUF: confirm the file's version is supported by the installed llama.cpp build; re-download if corrupt.
- Restart the engine extension if its IPC bridge died.
Example fix
// before
if (error instanceof Error && error.name === 'AbortError') throw error
throw new Error(i18n.t('model-errors:createModelFailed', { reason: describeEngineError(error) }))
// after
if (error instanceof Error && error.name === 'AbortError') throw error
const reason = describeEngineError(error)
console.error('[createModel] full error:', error)
throw new Error(
i18n.t('model-errors:createModelFailed', {
reason: reason || 'Unknown error. See console for details.',
})
) Defensive patterns
Strategy: try-catch
Type guard
function isAbortError(e: unknown): e is Error {
return e instanceof Error && e.name === 'AbortError'
} Try / catch
try {
this.model = await this.createModelOrAbort(modelId, updatedProvider ?? provider, mergedParams, providerId, options.abortSignal)
} catch (error) {
useAppState.getState().updateLoadingModel(false)
useAppState.getState().updateThreadLoadingModel(threadId, false)
if (isAbortError(error)) throw error // user pressed Stop — preserve identity
console.error('[createModel] underlying error:', error)
throw new Error(i18n.t('model-errors:createModelFailed', { reason: describeEngineError(error) }))
} Prevention
- For local models: confirm the GGUF exists and is supported before loading; reduce ctx_len/GPU layers on OOM.
- For remote providers: validate API key and base URL in provider settings before sending.
- Watch the console for the underlying engine error describeEngineError extracts.
- Restart the engine extension if its IPC bridge crashed.
When it happens
Trigger: llama.cpp server failed to load the GGUF (corrupt/unsupported file, OOM, missing mmproj); remote provider returned auth failure during model init (401/403); the model binary path is wrong; the engine extension threw during instantiation; context-length or GPU-layer settings exceed hardware.
Common situations: Insufficient RAM/VRAM to load the model; wrong API key for an OpenAI-compatible provider; GGUF version unsupported by the installed llama.cpp build; model file truncated/corrupted; engine extension crashed and its IPC bridge is down.
Related errors
- ServiceHub not initialized or model/provider missing.
- ${friendly} (${requestUrlOf(input)})
- model-errors:startModelFailed
- llamacpp extension not available
- Failed to determine embedding context size: ${e instanceof E
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/220d53dd28ea4b5e.
Report an issue: GitHub.