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

  1. Delete the existing model with that ID first (via the delete API), then re-import
  2. Use a unique model.id for the new import
  3. Remove leftover model directories from previous failed installs
  4. 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

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


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)