{"record":{"id":"6a72751f9cdf4236","repo":"nocobase/nocobase","slug":"backup-file-not-found-resolvedfile","errorCode":null,"errorMessage":"Backup file not found: ${resolvedFile}","messagePattern":"Backup file not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/cli/src/lib/backup.ts","lineNumber":188,"sourceCode":"  try {\n    const stats = await fs.stat(resolvedOutput);\n    if (stats.isDirectory()) {\n      return path.join(resolvedOutput, remoteName);\n    }\n  } catch {\n    // Treat non-existing paths as an explicit target file path.\n  }\n\n  return resolvedOutput;\n}\n\nexport async function resolveBackupRestoreFilePath(file: string) {\n  const resolvedFile = path.resolve(process.cwd(), file);\n  let stats;\n  try {\n    stats = await fs.stat(resolvedFile);\n  } catch {\n    throw new Error(`Backup file not found: ${resolvedFile}`);\n  }\n\n  if (!stats.isFile()) {\n    throw new Error(`Backup restore input must be a file: ${resolvedFile}`);\n  }\n\n  return resolvedFile;\n}\n\nexport function resolveBackupWaitApiBaseUrl(env: Env) {\n  const baseUrl = String(env.baseUrl ?? '').trim();\n  if (baseUrl) {\n    return baseUrl.replace(/\\/+$/, '');\n  }\n\n  const appPort =\n    env.appPort === undefined || env.appPort === null\n      ? ''","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/core/cli/src/lib/backup.ts#L170-L206","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the resolved absolute path in the error and verify the file exists there (ls the directory).","Run the command from the directory containing the backup, or pass an absolute path to the .nocobase-backup file.","Re-download the backup with `nb backup download` if the local file was deleted.","Fix filesystem permissions if the file exists but stat fails with EACCES."],"exampleFix":"// before\nnb backup restore-upload ./backup.nocobase-backup   # run from wrong cwd\n// after\nnb backup restore-upload /absolute/path/to/backup.nocobase-backup","handlingStrategy":"validation","validationCode":"import { promises as fs } from 'node:fs';\nasync function assertBackupFileExists(file: string) {\n  await fs.access(path.resolve(process.cwd(), file));\n}","typeGuard":"async function isReadableFile(p: string): Promise<boolean> {\n  try { return (await fs.stat(p)).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await nb(['backup', 'restore-upload', file]);\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('Backup file not found')) {\n    console.error(`Verify path exists: ${file} (cwd: ${process.cwd()})`);\n  } else throw error;\n}","preventionTips":["Use absolute paths for restore inputs in scripts.","Download with `nb backup download` immediately before restoring so the file is current.","Beware quoted shell globs that prevent expansion."],"tags":["filesystem","cli","backup","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}