janhq/jan · error · Error

Invalid modelId: . Only alphanumeric and / _ - . characters…

Error message

Invalid modelId: ${modelId}. Only alphanumeric and / _ - . characters are allowed.

What it means

The MLX extension's import() method validates the modelId before creating the model's config directory. isValidModelId rejects any id containing characters outside [A-Za-z0-9/_.-], because the id is used to build a filesystem path (providerPath/models/<modelId>/model.yml) and must not break path structure or enable path traversal.

Solutions

  1. Sanitize the modelId to only alphanumeric and / _ - . characters before calling import()
  2. Use the standard id form (e.g. 'org/repo-name' or 'org_repo') instead of a URL or path
  3. Trim whitespace and reject/replace illegal characters at the call site
  4. If importing a URL, pass it via opts.modelPath, not modelId

Example fix

// before
await mlx.import('https://huggingface.co/mlx-community/Llama-3 8B', { modelPath: '...' })
// after
await mlx.import('mlx-community/Llama-3-8B', { modelPath: '...' })
Defensive patterns

Strategy: validation

Validate before calling

const isValidModelId = (id) => typeof id === 'string' && /^[A-Za-z0-9/_.\-]+$/.test(id)
if (!isValidModelId(modelId)) throw new Error(`Invalid modelId: ${modelId}`)

Type guard

const isValidModelId = (id: unknown): id is string =>
  typeof id === 'string' && id.length > 0 && /^[A-Za-z0-9/_.\-]+$/.test(id)

Try / catch

try {
  await mlx.import(modelId, opts)
} catch (e) {
  if (String(e).includes('Invalid modelId')) {
    throw new Error(`modelId "${modelId}" contains illegal characters; use [A-Za-z0-9/_.-] only`)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling MlxExtension.import(modelId, opts) with a modelId containing spaces, URL-encoding, query strings, backslashes, colons (e.g. 'hf.co:org/model'), '..', or any other character outside alphanumeric and / _ - . .

Common situations: Passing a full Hugging Face URL instead of an id; copying a Windows path with backslashes as the id; ids with spaces from a UI input; ids copied with trailing whitespace or newline.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/690d78c4d54f2041. Report an issue: GitHub.

Appendix: source

Thrown at extensions/mlx-extension/src/index.ts:607

    }
    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))
      throw new Error(
        `Invalid modelId: ${modelId}. Only alphanumeric and / _ - . characters are allowed.`
      )

    const configPath = await joinPath([
      await this.getProviderPath(),
      'models',
      modelId,
      'model.yml',
    ])
    if (await fs.existsSync(configPath))
      throw new Error(`Model ${modelId} already exists`)

    const sourcePath = opts.modelPath

    if (sourcePath.startsWith('https://')) {
      // Download from URL to mlx models folder
      const janDataFolderPath = await getJanDataFolderPath()
      const modelDir = await joinPath([

View on GitHub (pinned to 7205d770c1)