actualbudget/actual · error
Invalid parameters
Error message
Invalid parameters
What it means
updateFileOwner validates its arguments up front and throws 'Invalid parameters' if either ownerId or fileId is falsy (null, undefined, empty string, 0). It is a guard to prevent issuing a meaningless UPDATE against the files table. No database access happens when this fires.
Source
Thrown at packages/sync-server/src/services/user-service.ts:131
try {
getAccountDb().transaction(() => {
const ownerExists = getUserById(ownerId);
if (!ownerExists) {
throw new Error('New owner not found');
}
getAccountDb().mutate('UPDATE files set owner = ? WHERE owner = ?', [
ownerId,
oldUserId,
]);
});
} catch (error) {
throw new Error(`Failed to transfer files: ${error.message}`);
}
}
export function updateFileOwner(ownerId, fileId) {
if (!ownerId || !fileId) {
throw new Error('Invalid parameters');
}
try {
const result = getAccountDb().mutate(
'UPDATE files set owner = ? WHERE id = ?',
[ownerId, fileId],
);
if (result.changes === 0) {
throw new Error('File not found');
}
} catch (error) {
throw new Error(`Failed to update file owner: ${error.message}`);
}
}
export function getUserAccess(fileId, userId, isAdmin) {
return getAccountDb().all(
`SELECT users.id as userId, user_name as userName, files.owner, display_name as displayName
FROM usersView on GitHub (pinned to d4334cb6e6)
Solutions
- Validate both ownerId and fileId are non-empty strings before calling updateFileOwner
- If ids come from an HTTP request, return a 400 to the client when they are missing instead of reaching the service
- Trace upstream lookups: if an id is undefined, fix the lookup that produced it, not this call
- Check for renamed request fields or payload-shape changes after upgrades
Example fix
// before
await updateFileOwner(body.ownerId, body.fileId);
// after
if (!body.ownerId || !body.fileId) {
return res.status(400).json({ error: 'ownerId and fileId are required' });
}
await updateFileOwner(body.ownerId, body.fileId); Defensive patterns
Strategy: validation
Validate before calling
function assertNonEmpty(value, name) {
if (typeof value !== 'string' || value.length === 0) {
throw new Error(`${name} is required`);
}
}
assertNonEmpty(ownerId, 'ownerId');
assertNonEmpty(fileId, 'fileId'); Type guard
function hasValidIds(input) {
return typeof input?.ownerId === 'string' && input.ownerId.length > 0 &&
typeof input?.fileId === 'string' && input.fileId.length > 0;
} Try / catch
try {
updateFileOwner(ownerId, fileId);
} catch (e) {
if (e.message.includes('Invalid parameters')) {
throw new BadRequestError('ownerId and fileId are required');
}
throw e;
} Prevention
- Validate request bodies at the route layer before calling service functions
- Never forward results of failed lookups (null/undefined ids) into service calls
- Fix field renames in payloads after upgrades
- Use a shared assert-id helper for all id parameters
When it happens
Trigger: Calling updateFileOwner(ownerId, fileId) with either argument missing — e.g. an API request body that omitted ownerId or fileId, an id variable that was undefined because an earlier lookup failed, or an empty string from an unset environment/config value.
Common situations: HTTP handlers forwarding req.body fields without validation; a getFileById/user lookup returning null earlier in the chain and the null being passed onward; refactors renaming fields so the old property name resolves to undefined.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- The provided userIds must be a non-empty array.
- Invalid --name: must be a non-empty string.
- No update fields provided. Use --name or --offbudget.
- Invalid cutoff date: expected a valid date (e.g. YYYY-MM-DD)
- No update fields provided. Use --name or --hidden.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/e65738e74747d7e5.
Report an issue: GitHub.