nocobase/nocobase · error

Backup file not found: ${resolvedFile}

Error message

Backup file not found: ${resolvedFile}

What it means

resolveBackupRestoreFilePath resolves the user-supplied restore file against the current working directory and stats it. If fs.stat throws (path does not exist or is inaccessible), the CLI throws this error with the fully resolved absolute path, aborting the restore before any upload happens. Note it also fires when the path exists but is unreadable due to permissions (stat EACCES).

Source

Thrown at packages/core/cli/src/lib/backup.ts:188

  try {
    const stats = await fs.stat(resolvedOutput);
    if (stats.isDirectory()) {
      return path.join(resolvedOutput, remoteName);
    }
  } catch {
    // Treat non-existing paths as an explicit target file path.
  }

  return resolvedOutput;
}

export async function resolveBackupRestoreFilePath(file: string) {
  const resolvedFile = path.resolve(process.cwd(), file);
  let stats;
  try {
    stats = await fs.stat(resolvedFile);
  } catch {
    throw new Error(`Backup file not found: ${resolvedFile}`);
  }

  if (!stats.isFile()) {
    throw new Error(`Backup restore input must be a file: ${resolvedFile}`);
  }

  return resolvedFile;
}

export function resolveBackupWaitApiBaseUrl(env: Env) {
  const baseUrl = String(env.baseUrl ?? '').trim();
  if (baseUrl) {
    return baseUrl.replace(/\/+$/, '');
  }

  const appPort =
    env.appPort === undefined || env.appPort === null
      ? ''

View on GitHub (pinned to fa42722fef)

Solutions

  1. Check the resolved absolute path in the error and verify the file exists there (ls the directory).
  2. Run the command from the directory containing the backup, or pass an absolute path to the .nocobase-backup file.
  3. Re-download the backup with `nb backup download` if the local file was deleted.
  4. Fix filesystem permissions if the file exists but stat fails with EACCES.

Example fix

// before
nb backup restore-upload ./backup.nocobase-backup   # run from wrong cwd
// after
nb backup restore-upload /absolute/path/to/backup.nocobase-backup
Defensive patterns

Strategy: validation

Validate before calling

import { promises as fs } from 'node:fs';
async function assertBackupFileExists(file: string) {
  await fs.access(path.resolve(process.cwd(), file));
}

Type guard

async function isReadableFile(p: string): Promise<boolean> {
  try { return (await fs.stat(p)).isFile(); } catch { return false; }
}

Try / catch

try {
  await nb(['backup', 'restore-upload', file]);
} catch (error) {
  if (error instanceof Error && error.message.startsWith('Backup file not found')) {
    console.error(`Verify path exists: ${file} (cwd: ${process.cwd()})`);
  } else throw error;
}

Prevention

When it happens

Trigger: Calling `nb backup restore-upload <file>` (or restore flows that call resolveBackupRestoreFilePath) with a relative path from the wrong cwd, a typo'd filename, a file deleted/moved after download, or a path whose parent directory denies access.

Common situations: Running the restore from a different directory than where the backup was downloaded; shell glob not expanding (quoted wildcard); using a URL or remote name instead of a local file path; Windows/WSL path mismatches.

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 nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/6a72751f9cdf4236. Report an issue: GitHub.