janhq/jan · error · Error
Model with ID already exists
Error message
Model with ID ${model.id} already exists What it means
When adding/importing a model, the extension moves the model folder to <providerPath>/models/<model.id> and refuses to overwrite an existing directory, throwing this error if the target already exists. It prevents clobbering an installed model with the same ID.
Solutions
- Delete the existing model with that ID first (via the delete API), then re-import
- Use a unique model.id for the new import
- Remove leftover model directories from previous failed installs
- List installed models to check for ID collisions before importing
Example fix
// before
await mlx.importModel({ id: 'llama-3', folder })
// after
const models = await mlx.getModels()
if (!models.some(m => m.id === 'llama-3')) {
await mlx.importModel({ id: 'llama-3', folder })
} else {
await mlx.delete('llama-3')
await mlx.importModel({ id: 'llama-3', folder })
} Defensive patterns
Strategy: validation
Validate before calling
const models = await mlx.getModels()
if (models.some(m => m.id === newModel.id)) {
await mlx.delete(newModel.id) // or pick a unique id
}
await mlx.importModel(newModel) Type guard
const idIsFree = async (id) => !(await mlx.getModels()).some(m => m.id === id)
Try / catch
try {
await mlx.importModel(model)
} catch (e) {
if (String(e.message).includes('already exists')) {
await mlx.delete(model.id)
return mlx.importModel(model)
}
throw e
} Prevention
- Check the installed-model list for ID collisions before every import
- Clean up leftover folders after failed imports
- Generate unique IDs (suffix with timestamp) for repeated imports
- Never reuse an existing model's ID unless you intend replacement
When it happens
Trigger: Importing a model whose id collides with an already-installed model's directory — re-importing the same model, two models configured with identical IDs, or leftover folders from a previous failed install.
Common situations: Duplicate imports after a partial failure left the folder behind, users importing a model twice, ID case-sensitivity confusion, importing another model that happens to use the same ID string.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Model does not exist
- error.message
- File ' ' has already been attached to this project
- File ' ' has already been attached to this thread
- IO error
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/9132b8c393007fc9.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/mlx-extension/src/index.ts:588
modelId: string,
model: Partial<modelInfo>
): Promise<void> {
// Delegate to the same logic as llamacpp since they share the model dir
const modelFolderPath = await joinPath([
await this.getProviderPath(),
'models',
modelId,
])
const modelConfig = await invoke<ModelConfig>('read_yaml', {
path: await joinPath([modelFolderPath, 'model.yml']),
})
const newFolderPath = await joinPath([
await this.getProviderPath(),
'models',
model.id,
])
if (await fs.existsSync(newFolderPath)) {
throw new Error(`Model with ID ${model.id} already exists`)
}
const newModelConfigPath = await joinPath([newFolderPath, 'model.yml'])
await fs.mv(modelFolderPath, newFolderPath).then(() =>
invoke('write_yaml', {
data: {
...modelConfig,
model_path: modelConfig?.model_path?.replace(
`mlx/models/${modelId}`,
`mlx/models/${model.id}`
),
},
savePath: newModelConfigPath,
})
)
}
override async import(modelId: string, opts: ImportOptions): Promise<void> {
if (!isValidModelId(modelId))View on GitHub (pinned to 7205d770c1)