actualbudget/actual · error · Error
Authentication required. Provide --password or --session-tok
Error message
Authentication required. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.
What it means
withConnection wraps every data command; it builds the runtime configuration and refuses to proceed without credentials. When neither password-based nor session-token-based authentication is configured (CLI flag, env var, or config file), it throws this error instead of attempting a doomed connection. This is a fail-fast guard mirroring resolveConfig's auth requirement at the command layer.
Source
Thrown at packages/cli/src/connection.ts:64
info(`Connecting to ${config.serverUrl}...`, globalOpts.verbose);
if (config.sessionToken) {
await api.init({
serverURL: config.serverUrl,
dataDir: config.dataDir,
sessionToken: config.sessionToken,
verbose: globalOpts.verbose,
});
} else if (config.password) {
await api.init({
serverURL: config.serverUrl,
dataDir: config.dataDir,
password: config.password,
verbose: globalOpts.verbose,
});
} else {
throw new Error(
'Authentication required. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.',
);
}
try {
if (skipBudget) return await fn(config);
if (!config.syncId) {
throw new Error(
'Sync ID is required for this command. Set --sync-id or ACTUAL_SYNC_ID.',
);
}
const meta = getMetaDir(config.dataDir, config.syncId);
let release: Release | null = null;
if (!config.noLock) {
release = mutates
? await acquireExclusive(meta, {
timeoutMs: config.lockTimeout * 1000,View on GitHub (pinned to d4334cb6e6)
Solutions
- Export ACTUAL_PASSWORD or ACTUAL_SESSION_TOKEN before running the command.
- Pass --password or --session-token directly to the command.
- Store credentials in the config file and confirm that config file is the one loaded.
- Print/inspect the resolved environment in CI (`env | grep ACTUAL`) to confirm the secrets exist.
Example fix
// before $ actual-cli accounts --sync-id $ID Error: Authentication required... // after $ export ACTUAL_SESSION_TOKEN=... $ actual-cli accounts --sync-id $ID
Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.ACTUAL_PASSWORD && !process.env.ACTUAL_SESSION_TOKEN) {
throw new Error('Set ACTUAL_PASSWORD or ACTUAL_SESSION_TOKEN before running CLI commands.');
} Type guard
function hasAuth(o: { password?: string; sessionToken?: string }): boolean {
return typeof o.password === 'string' && o.password.length > 0 ||
typeof o.sessionToken === 'string' && o.sessionToken.length > 0;
} Try / catch
try {
await withConnection(opts, fn);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Authentication required')) {
console.error('No credentials found: pass --password/--session-token or export ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN.');
process.exit(1);
}
throw err;
} Prevention
- Export credentials in shell profiles used by automation, not just interactive shells.
- In CI, map secrets to the exact env names ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.
- Use a session token workflow to avoid password handling.
- Add a preflight env check at the top of wrapper scripts.
When it happens
Trigger: Running any accounts/budgets/categories/payees/query command where config lacks both password and sessionToken across --password/--session-token flags, ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN, and config file entries.
Common situations: Interactive shell without the env vars exported (set in a different terminal or only in .bashrc after su); CI job missing secrets; typo'd env var names.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Authentication required. Set --password/--session-token, ACT
- Server URL is required. Set --server-url, ACTUAL_SERVER_URL
- 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)
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/f1150201aa638d0f.
Report an issue: GitHub.