actualbudget/actual · error · PostError
unknown
unknown
Error message
res.description || res.reason || 'unknown'
What it means
`del` throws this PostError when the server responds 200 with JSON whose status is not 'ok'; the message is the server's `description` or `reason`, else 'unknown'. It is a server-reported application failure for the delete operation, with request data and response logged.
Source
Thrown at packages/loot-core/src/server/post.ts:165
try {
res = JSON.parse(text);
} catch {
// Something seriously went wrong. TODO handle errors
throw new PostError('parse-json', { meta: text });
}
if (res.status !== 'ok') {
logger.log(
'API call failed: ' +
url +
'\nData: ' +
JSON.stringify(data, null, 2) +
'\nResponse: ' +
JSON.stringify(res, null, 2),
);
throw new PostError(res.description || res.reason || 'unknown');
}
return res.data;
}
export async function patch(url, data, headers = {}, timeout = null) {
let text;
let res;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const signal = timeout ? controller.signal : null;
res = await fetch(url, {
method: 'PATCH',
body: JSON.stringify(data),
signal,
headers: {View on GitHub (pinned to d4334cb6e6)
Solutions
- Check the thrown message and the logged request/response for the server's reason.
- Re-authenticate if the reason indicates an unauthorized/token problem.
- Confirm the file still exists and belongs to the current user before deleting.
- Check sync server logs for the failing request when the message is 'unknown'.
- Align client and server versions.
Example fix
// before: deleting with a token from a different user account
await del(server + '/delete-user-file', { token: otherUserToken, fileId });
// after: ensure the file belongs to the signed-in user
const files = await getServerFiles(token); // verify ownership first
if (files.some(f => f.fileId === fileId)) await del(server + '/delete-user-file', { token, fileId }); Defensive patterns
Strategy: try-catch
Validate before calling
// check ownership before deleting
const files = await getServerFiles(token);
if (!files.some(f => f.fileId === fileId)) throw new Error(`File ${fileId} not found for current user`); Type guard
function isServerRejection(e: unknown): e is { reason: string } {
return typeof e === 'object' && e !== null && typeof (e as any).reason === 'string' && (e as any).reason !== 'ok';
} Try / catch
try {
await del(server + '/delete-user-file', { token, fileId });
} catch (e) {
if (isServerRejection(e) && /token|unauthorized/i.test(e.message)) {
await reauthenticate();
} else if (isServerRejection(e) && /not-found/i.test(e.message)) {
// file already gone: treat as idempotent success
} else throw e;
} Prevention
- Validate ownership/existence of server-side resources before delete.
- Handle 'file-not-found' as an idempotent outcome where safe.
- Refresh tokens proactively rather than reusing long-lived ones.
- Capture the logged request/response on 'unknown' reasons for support requests.
When it happens
Trigger: del() call rejected by the server: invalid/expired user token, file ID not owned by the user, or other server-side validation on the delete endpoint responding {status: ..., description/reason}.
Common situations: Token expired after server maintenance; attempting to delete a file already removed server-side; permission mismatch between the signed-in user and the file's owner; 'unknown' from a server version that omits reason fields.
Related errors
- responseData.description || responseData.reason || 'unknown'
- response.reason || response.error || fallbackMessage
- openid-grant-failed
- token-expired
- network-failure
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/84c7b573f43253b7.
Report an issue: GitHub.