janhq/jan · error
Model already loaded!
Error message
Model already loaded!
What it means
load() first checks findSessionByModel; if a session for that modelId already exists it throws 'Model already loaded!' instead of starting a duplicate server process. This is a deliberate guard against double-loading the same MLX model.
Solutions
- Check whether the model is loaded first (findSessionByModel/sessionInfo) and reuse the existing session instead of calling load
- Unload the existing session (unload(modelId)) before loading again if a fresh load is required
- If the session is stale (process actually dead), clear stale session state/restart the app then retry
- Guard call sites so load is only invoked when not already loaded/loading
Example fix
// before await mlx.load(modelId) // after const existing = await mlx.getSessionInfo(modelId) const session = existing ?? (await mlx.load(modelId))
Defensive patterns
Strategy: try-catch
Validate before calling
// Check before load
const existing = await mlx.getSessionInfo(modelId)
if (existing) throw new Error(`${modelId} already loaded; reuse it`) Try / catch
try {
await mlx.load(modelId)
} catch (e) {
if (!String(e).includes('Model already loaded')) throw e
// reuse existing session
} Prevention
- Look up existing sessions before loading
- Serialize load calls per modelId (single-flight) in UI code
- Unload explicitly before intentional reloads
- Clear stale session state after crashes before reloading
When it happens
Trigger: Calling load(modelId) when the model is already running — e.g. clicking Load twice, loading from two UI surfaces, or a previous session that never unloaded (stale session record).
Common situations: Double-clicking load buttons, race between UI state and backend state after a crash that left a session record, or re-running a script that loads models without unloading first.
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
- No active MLX session found for model
- error.message
- IO error
- MLX API request failed with status
- MLX model appears to have crashed! Please reload!
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/c66a80bdb2cee336.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/mlx-extension/src/index.ts:246
private async getRandomPort(): Promise<number> {
try {
return await invoke<number>('plugin:mlx|get_mlx_random_port')
} catch {
logger.error('Unable to find a suitable port for MLX server')
throw new Error('Unable to find a suitable port for MLX model')
}
}
override async load(
modelId: string,
overrideSettings?: any,
isEmbedding: boolean = false,
bypassAutoUnload: boolean = false
): Promise<SessionInfo> {
const sInfo = await this.findSessionByModel(modelId)
if (sInfo) {
throw new Error('Model already loaded!')
}
if (this.loadingModels.has(modelId)) {
return this.loadingModels.get(modelId)!
}
const loadingPromise = this.performLoad(
modelId,
overrideSettings,
isEmbedding,
bypassAutoUnload
)
this.loadingModels.set(modelId, loadingPromise)
try {
return await loadingPromise
} finally {
this.loadingModels.delete(modelId)View on GitHub (pinned to 7205d770c1)