actualbudget/actual · error
invalid-file-id
invalid-file-id
Error message
File not found at server
What it means
The file deletion/validation path calls `UserService.getFileById(fileId)`; if no file row matches, it responds 404 with reason 'invalid-file-id' and details 'File not found at server'. The server only permits operations on files it actually tracks in its files table.
Source
Thrown at packages/sync-server/src/app-admin.js:208
const { granted } = UserService.checkFilePermission(
fileId,
res.locals.user_id,
) || {
granted: 0,
};
if (granted === 0 && !isAdmin(res.locals.user_id)) {
res.status(403).send({
status: 'error',
reason: 'forbidden',
details: 'permission-not-found',
});
return false;
}
const fileIdInDb = UserService.getFileById(fileId);
if (!fileIdInDb) {
res.status(404).send({
status: 'error',
reason: 'invalid-file-id',
details: 'File not found at server',
});
return false;
}
const accesses = UserService.getUserAccess(
fileId,
res.locals.user_id,
isAdmin(res.locals.user_id),
);
res.json(accesses);
});
app.post('/access', (req, res) => {
const userAccess = req.body || {};View on GitHub (pinned to d4334cb6e6)
Solutions
- Verify the fileId against the server's file list (user-get-files) and use only ids present there.
- Treat 404 as already-deleted and remove the file from local metadata instead of retrying.
- Confirm the client is connected to the same sync server that hosts the file (check GOAL_SERVER_URL / server URL config).
- If the file should exist, re-upload/sync it from the client to register it, then retry the operation.
Example fix
// before
await deleteFile({ fileId: localFileId }); // file never synced to this server
// after
const files = await getUserFiles();
if (files.some(f => f.fileId === localFileId)) {
await deleteFile({ fileId: localFileId });
} Defensive patterns
Strategy: validation
Validate before calling
const files = await getUserFiles(); // server-side listing
if (!files.some(f => f.fileId === fileId)) {
throw new Error(`File ${fileId} not present on server; nothing to delete`);
} Type guard
function isKnownFileId(fileId: string, serverFiles: { fileId: string }[]): boolean {
return serverFiles.some(f => f.fileId === fileId);
} Try / catch
try {
await deleteFile({ fileId });
} catch (e) {
if (e.status === 404 && e.reason === 'invalid-file-id') {
// already deleted or never synced: clean up local metadata only
return;
}
throw e;
} Prevention
- Validate fileIds against the server listing before delete/sync operations.
- Treat 404 invalid-file-id as success in cleanup scripts (idempotent deletes).
- Confirm the client's sync-server URL matches the server that hosts the file.
- Remove stale local file metadata after successful deletion to prevent repeats.
When it happens
Trigger: DELETE /user-delete-file (or similar file endpoint) with a fileId that does not exist on the server — already deleted, a local-only file never synced, an id from another server, or a mistyped uuid.
Common situations: Deleting a file on the server after it was already removed (double cleanup); pointing a client at a fresh sync-server instance while reusing ids from the old instance; local files created offline that were never uploaded; corrupted client metadata holding stale file ids.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- cannot-find-user-to-update
- new-user-not-found
- No id returned from download.
- response.reason || response.error_code
- response.reason || response.error || fallbackMessage
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/69c1dffa3f92f283.
Report an issue: GitHub.