janhq/jan · error

File not found

Error message

File not found: ${path}

What it means

The load-model path resolves opts.modelPath and opts.mmprojPath via maybeDownload(): remote URLs are downloaded, while local absolute paths are checked with fs.existsSync(). If a local path does not exist, 'File not found: <path>' is thrown before any model loading begins.

Solutions

  1. Verify the file exists at the given path (ls/Check on disk) and fix opts.modelPath / opts.mmprojPath
  2. Point the model config to the correct location or re-import the model with valid paths
  3. Re-download the model if the file was lost
  4. Check the Jan data folder location did not change between versions and update configs accordingly

Example fix

// before
await loadModel({ modelPath: '/old/path/model.gguf' })
// after
if (!fs.existsSync('/new/path/model.gguf')) throw new Error('check path')
await loadModel({ modelPath: '/new/path/model.gguf' })
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'fs'
for (const p of [opts.modelPath, opts.mmprojPath]) {
  if (p && !p.startsWith('http') && !existsSync(p)) throw new Error(`missing file: ${p}`)
}
await loadModel(opts)

Type guard

const isExistingLocalFile = (p: unknown): p is string =>
  typeof p === 'string' && !/^https?:\/\//.test(p) && existsSync(p)

Try / catch

try {
  await loadModel(opts)
} catch (e) {
  if (e.message.startsWith('File not found:')) {
    const missing = e.message.slice('File not found: '.length)
    await redownloadOrRelocate(missing); return loadModel(opts)
  }
  throw e
}

Prevention

When it happens

Trigger: Loading a model with opts.modelPath or opts.mmprojPath set to an absolute local path where the .gguf file does not exist; a moved/renamed/deleted model file; a wrong path in model.yml.

Common situations: Model file deleted from disk or moved to another drive; path recorded under an old data-folder location after an app update/migration; typo in the path; mount/external drive not connected.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

              ? 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
    // Speculative-decoding draft companion; paired with the main model. The
    // file name stays `mtp.gguf` for every flavour: it is the local name of
    // the paired draft, and changing it would orphan existing installs.
    let draftModelPath = opts.specDraftPath
      ? await maybeDownload(opts.specDraftPath, 'mtp.gguf')
      : undefined

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

View on GitHub (pinned to 7205d770c1)