janhq/jan · error · Error

File not found: ${path}

Error message

File not found: ${path}

What it means

Thrown inside maybeDownload() (runImport's local-file branch) when opts.modelPath / opts.mmprojPath / opts.mtpPath is not an https URL and the file at that absolute local path does not exist on disk. maybeDownload routes https:// paths into the download queue and treats everything else as a local file - this guard verifies the local file is actually present before import proceeds to GGUF validation.

Source

Thrown at extensions/llamacpp-extension/src/index.ts:3136

              ? opts.modelSha256
              : saveName === 'mmproj.gguf'
                ? opts.mmprojSha256
                : undefined,
          size:
            saveName === 'model.gguf'
              ? opts.modelSize
              : saveName === 'mmproj.gguf'
                ? opts.mmprojSize
                : undefined,
          model_id: modelId,
        })
        return localPath
      }

      // if local file (absolute path), check if it exists
      // and return the path
      if (!(await fs.existsSync(path)))
        throw new Error(`File not found: ${path}`)
      return path
    }

    let modelPath = await maybeDownload(opts.modelPath, 'model.gguf')
    let mmprojPath = opts.mmprojPath
      ? await maybeDownload(opts.mmprojPath, 'mmproj.gguf')
      : undefined
    // MTP draft companion (speculative decoding); paired with the main model.
    let mtpModelPath = opts.mtpPath
      ? await maybeDownload(opts.mtpPath, 'mtp.gguf')
      : undefined

    if (downloadItems.length > 0) {
      try {
        // emit download update event on progress
        const onProgress = (transferred: number, total: number) => {
          events.emit(DownloadEvent.onFileDownloadUpdate, {
            modelId,

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Verify the absolute path is correct and the file exists before calling import (run fs.existsSync yourself).
  2. If the file moved, re-locate it and pass the updated path.
  3. If the model is remote, pass an https:// URL instead of a local path so maybeDownload routes it to the downloader.
  4. Normalize the path (resolve symlinks, convert relative to absolute) before passing it in.

Example fix

// before
await provider.import('x', { modelPath: '/mnt/models/qwen.gguf' }) // throws - file moved
// after
const p = '/mnt/models/qwen.gguf'
if (!(await fs.existsSync(p))) throw new Error(`please re-pick the model file; not found at ${p}`)
await provider.import('x', { modelPath: p })
Defensive patterns

Strategy: validation

Validate before calling

// Verify local file existence before import (URL branch handled separately)
async function assertLocalFileExists(p: string) {
  if (!p.startsWith('https://') && !(await fs.existsSync(p))) {
    throw new Error(`Model file not found on disk: ${p}. Re-pick the file or pass an https URL.`)
  }
}
await assertLocalFileExists(opts.modelPath)
if (opts.mmprojPath) await assertLocalFileExists(opts.mmprojPath)
if (opts.mtpPath) await assertLocalFileExists(opts.mtpPath)

Type guard

async function localFileExists(p: string): Promise<boolean> {
  if (p.startsWith('https://')) return true
  return fs.existsSync(p)
}

Try / catch

try { await provider.import(modelId, opts) }
catch (e) {
  if (/File not found/.test(String(e))) { opts.modelPath = await rePromptForFile(); await provider.import(modelId, opts) }
  else throw e
}

Prevention

When it happens

Trigger: Passing modelPath as a local path to a file that was moved, deleted, or never downloaded; passing a relative path when an absolute path is expected; pointing at the wrong drive/mount on Windows/Linux; the mmproj path was optional-looking but actually supplied and missing.

Common situations: User picked a model file in the file dialog then moved it before import finished. Path uses Windows backslashes or a different volume label than where the file lives. Network mount disconnected. Typo in the path. Symlink that points to a removed target.

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/26cc845ab0cae05f. Report an issue: GitHub.