{"record":{"id":"f1150201aa638d0f","repo":"actualbudget/actual","slug":"authentication-required-provide-password-or-s","errorCode":null,"errorMessage":"Authentication required. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.","messagePattern":"Authentication required\\. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/connection.ts","lineNumber":64,"sourceCode":"\n  info(`Connecting to ${config.serverUrl}...`, globalOpts.verbose);\n\n  if (config.sessionToken) {\n    await api.init({\n      serverURL: config.serverUrl,\n      dataDir: config.dataDir,\n      sessionToken: config.sessionToken,\n      verbose: globalOpts.verbose,\n    });\n  } else if (config.password) {\n    await api.init({\n      serverURL: config.serverUrl,\n      dataDir: config.dataDir,\n      password: config.password,\n      verbose: globalOpts.verbose,\n    });\n  } else {\n    throw new Error(\n      'Authentication required. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.',\n    );\n  }\n\n  try {\n    if (skipBudget) return await fn(config);\n    if (!config.syncId) {\n      throw new Error(\n        'Sync ID is required for this command. Set --sync-id or ACTUAL_SYNC_ID.',\n      );\n    }\n\n    const meta = getMetaDir(config.dataDir, config.syncId);\n    let release: Release | null = null;\n    if (!config.noLock) {\n      release = mutates\n        ? await acquireExclusive(meta, {\n            timeoutMs: config.lockTimeout * 1000,","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/cli/src/connection.ts#L46-L82","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$ actual-cli accounts --sync-id $ID\nError: Authentication required...\n// after\n$ export ACTUAL_SESSION_TOKEN=...\n$ actual-cli accounts --sync-id $ID","handlingStrategy":"validation","validationCode":"if (!process.env.ACTUAL_PASSWORD && !process.env.ACTUAL_SESSION_TOKEN) {\n  throw new Error('Set ACTUAL_PASSWORD or ACTUAL_SESSION_TOKEN before running CLI commands.');\n}","typeGuard":"function hasAuth(o: { password?: string; sessionToken?: string }): boolean {\n  return typeof o.password === 'string' && o.password.length > 0 ||\n         typeof o.sessionToken === 'string' && o.sessionToken.length > 0;\n}","tryCatchPattern":"try {\n  await withConnection(opts, fn);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Authentication required')) {\n    console.error('No credentials found: pass --password/--session-token or export ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["auth","cli","env"],"backgroundTag":"missing-credentials","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}