actualbudget/actual · error
response.reason || response.error || fallbackMessage
Error message
response.reason || response.error || fallbackMessage
What it means
The second branch of `ensureSuccessResponse`: when the sync-server response carries an `error` (without an `error_code`), it throws `response.reason || response.error || fallbackMessage`. The `fallbackMessage` (passed by each provider's reset handler, e.g. 'Failed to set GoCardless secret') is only used when neither `reason` nor `error` carry text. This is the generic failure path for provider secret-set calls.
Source
Thrown at packages/desktop-client/src/components/banksync/useBuiltInBankSyncProviders.ts:103
}
if (isAdmin) {
return null;
}
return isFileOwner ? 'file-owner' : 'general';
}
async function ensureSuccessResponse(
response: SecretSetResponse,
fallbackMessage: string,
) {
if (response?.error_code) {
throw new Error(response.reason || response.error_code);
}
if (response?.error) {
throw new Error(response.reason || response.error || fallbackMessage);
}
}
export function useBuiltInBankSyncProviders({
upgradingAccountId,
}: UseBuiltInBankSyncProvidersOptions = {}) {
const { t } = useTranslation();
const dispatch = useDispatch();
const syncServerStatus = useSyncServerStatus();
const { cloudFileId, isAdmin, isFileOwner } = useCurrentAccess();
const canConfigureProviders = isAdmin;
const [isGoCardlessSetupComplete, setIsGoCardlessSetupComplete] = useState<
boolean | null
>(null);
const [isSimpleFinSetupComplete, setIsSimpleFinSetupComplete] = useState<
boolean | null
>(null);View on GitHub (pinned to d4334cb6e6)
Solutions
- Check the sync-server logs at the time of the request — the thrown message's `reason`/`error` text points to the server-side cause.
- Verify the sync-server is online and reachable (`syncServerStatus`) and the user has admin rights before configuring providers.
- Confirm server storage (secrets table / key store) is writable and the server version matches the client.
- Retry the credential submission after fixing the server-side condition; if the message equals the generic fallback only, add logging to capture the full server response.
Example fix
// before
await ensureSuccessResponse(res, 'Failed to set Akahu secret');
// after
try {
await ensureSuccessResponse(res, 'Failed to set Akahu secret');
} catch (e) {
logger.error('Akahu secret-set failed', { response: res });
setError(e.message === 'Failed to set Akahu secret'
? 'Unknown server error — check sync-server logs'
: e.message);
} Defensive patterns
Strategy: fallback
Validate before calling
if (syncServerStatus !== 'online') {
setError('Bank sync requires a connected sync server. Start the server and sign in first.');
return;
}
if (!isAdmin) { setError('Only admins can configure bank-sync providers.'); return; } Type guard
function hasServerError(
res: SecretSetResponse,
): res is SecretSetResponse & { error: string } {
return typeof res?.error === 'string' && res.error.length > 0;
} Try / catch
try {
await ensureSuccessResponse(res, 'Failed to set secret');
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (msg === fallbackMessage) {
// Neither reason nor error had text — capture raw response for support
logger.error('secret-set failed with no reason', { res });
setError(fallbackMessage + ' (check sync-server logs for details)');
} else {
setError(msg);
}
} Prevention
- Ensure the sync-server is online and reachable before opening provider settings.
- Verify the server's secrets storage (database) is healthy and writable.
- Keep client and server versions aligned so error responses always include `reason` text.
- Log the full server response on failure so the generic fallback message never hides the root cause.
When it happens
Trigger: A reset/save of any bank-sync provider secret (GoCardless, SimpleFin, PluggyAI, EnableBanking, Akahu) where the sync-server returns `{ error: '...' }` with no `error_code` — server-side exception during secret storage, network/DB failure on the server, or provider upstream call failing with only a free-form error string.
Common situations: Self-hosted sync-server with database/storage issues; server unreachable mid-request returning a wrapped error; provider API outage causing upstream failure surfaced as a plain error; unauthenticated request to the sync-server.
Related errors
- response.reason || response.error_code
- responseData.description || responseData.reason || 'unknown'
- unknown
- No id returned from download.
- Account with ID ${upgradingId} not found.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/9e29c79445bb3864.
Report an issue: GitHub.