nocobase/nocobase · error
Backup file ${filterByTk} not found
Error message
Backup file ${filterByTk} not found What it means
Thrown by the backup-files download action when the requested backup either does not resolve to a downloadable state or its name lacks the DUMPED_EXTENSION suffix. The action verifies via Dumper.getFileStatus that the target exists with status 'ok' before streaming it as an attachment; otherwise it reports the file as not found.
Source
Thrown at packages/plugins/@nocobase/plugin-backup-restore/src/server/resourcers/backup-files.ts:142
await next();
},
/**
* download backup file
* @param ctx
* @param next
*/
async download(ctx, next) {
const { filterByTk } = ctx.action.params;
const dumper = new Dumper(ctx.app);
const filePath = dumper.backUpFilePath(filterByTk);
const fileState = await Dumper.getFileStatus(filePath);
if (!filterByTk.endsWith(`.${DUMPED_EXTENSION}`) || fileState.status !== 'ok') {
throw new Error(`Backup file ${filterByTk} not found`);
}
ctx.attachment(filePath);
ctx.body = fs.createReadStream(filePath);
await next();
},
async restore(ctx, next) {
const { dataTypes, filterByTk, key } = ctx.action.params.values;
const filePath = (() => {
if (key) {
const tmpDir = os.tmpdir();
return path.resolve(tmpDir, key);
}
if (filterByTk) {
const dumper = new Dumper(ctx.app);View on GitHub (pinned to fa42722fef)
Solutions
- Refresh the backup-files list and confirm the file still exists on disk in the backup storage directory.
- Ensure filterByTk is the full file name including the DUMPED_EXTENSION (e.g. `backup-20260831.dump`).
- If status is stuck as in_progress, remove the stale .lock file for that backup and retry.
- Check that the app's backup storage path/volume points to the directory that actually contains the dump.
- Re-run a backup if the archive is gone.
Example fix
// before
await api.resource('backup-files').download({ filterByTk: 'backup-20260831' });
// after
const name = 'backup-20260831.dump'; // include extension, ensure exists
const list = await api.resource('backup-files').list({});
if (list.data.data.some((f) => f.name === name && f.status === 'ok')) {
await api.resource('backup-files').download({ filterByTk: name });
} Defensive patterns
Strategy: validation
Validate before calling
async function canDownload(name) {
if (!name.endsWith('.dump')) return false;
const { data } = await api.resource('backup-files').list({});
const f = data.data.find((x) => x.name === name);
return Boolean(f && f.status === 'ok');
}
// call before download Type guard
function isDownloadable(f) {
return f != null && f.status === 'ok' && typeof f.name === 'string' && f.name.endsWith('.dump');
} Try / catch
try {
await api.resource('backup-files').download({ filterByTk: name });
} catch (e) {
if (new RegExp(`Backup file ${name} not found`).test(e.message)) {
refreshBackupList(); // stale UI or deleted file
return;
}
throw e;
} Prevention
- Always pass the full file name including the .dump extension as filterByTk
- Refresh the backup list before offering download links
- Verify backup storage path/volume after server or container changes
- Check the file exists on disk before sharing download URLs
When it happens
Trigger: GET backup-files:download with filterByTk whose name doesn't end with the dumped extension (e.g. missing `.dump`), the file was deleted from storage, or getFileStatus returns status other than 'ok' (e.g. stale in_progress lock or unreadable path).
Common situations: UI list is stale and the row refers to a deleted file; backup storage volume was remounted/replaced; download link built from a name without extension; concurrent restore/cleanup removed the file between listing and download.
Related errors
- Backup file not found: ${resolvedFile}
- Backup restore input must be a file: ${resolvedFile}
- Lock file is not a file
- Path is not a file
- Env "${envName}" is not configured
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/f79ebdd244125a87.
Report an issue: GitHub.