actualbudget/actual · error

Invalid access key

Error message

Invalid access key

What it means

parseAccessKey validates a SimpleFIN access key against ACCESS_KEY_FORMAT before parsing it into scheme/auth/baseUrl parts. If the key is missing or doesn't match the expected format (roughly `https://user:pass@domain`), it throws 'Invalid access key'. The server never even attempts a network call with a malformed key.

Source

Thrown at packages/sync-server/src/app-simplefin/app-simplefin.js:322

      error_code: 'SERVER_DOWN',
      status: 'rejected',
      reason: 'There was an error communicating with SimpleFIN.',
    },
  });
}

const ACCESS_KEY_FORMAT = /^.*\/\/.*:.*@.*$/;

function parseAccessKey(accessKey) {
  let scheme = null;
  let rest = null;
  let auth = null;
  let username = null;
  let password = null;
  let baseUrl = null;
  if (!accessKey || !ACCESS_KEY_FORMAT.test(accessKey)) {
    console.log('Invalid SimpleFIN access key');
    throw new Error(`Invalid access key`);
  }
  [scheme, rest] = accessKey.split('//');
  [auth, rest] = rest.split('@');
  [username, password] = auth.split(':');
  baseUrl = `${scheme}//${rest}`;
  return {
    baseUrl,
    username,
    password,
  };
}

function decodeClaimUrl(base64Token) {
  const decoded = Buffer.from(base64Token, 'base64').toString();

  let url;
  try {
    url = new URL(decoded);

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Obtain a fresh access key from https://bridge.simplefin.org/auth/login and paste the complete key URL exactly as provided.
  2. Check the stored key starts with `https://` and contains `user:pass@host` parts; re-enter it if truncated.
  3. Make sure the claim step succeeded before persisting the key — a non-key string (e.g. an error message) will fail this check.
  4. Trim surrounding whitespace/quotes when storing or passing the key.

Example fix

// before
await setupSimplefin('abc123token');

// after
await setupSimplefin('https://demo:TOKEN@bridge.simplefin.org/sfin/xxx');
Defensive patterns

Strategy: validation

Validate before calling

const ACCESS_KEY_RE = /^https:\/\/[^:]+:[^@]+@.+$/;
if (!accessKey || !ACCESS_KEY_RE.test(accessKey.trim())) {
  throw new Error('Not a valid SimpleFIN access key URL');
}

Prevention

When it happens

Trigger: Providing an empty/undefined access key, or a key that isn't a SimpleFIN setup-token-style URL (e.g. pasting a plain token, a token with missing scheme or credentials, or one that has been truncated/corrupted) to parseAccessKey via the SimpleFIN setup/claim flow.

Common situations: User pasted only the temporary connection token instead of the full access key URL; key copied with whitespace or partially; using a key from a different service; the claim step failed earlier and an error string was stored as the key.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/2fa43879accfc56f. Report an issue: GitHub.