actualbudget/actual · error · Error
@actual-app/api requires a node version ${minimumNodeVersion
Error message
@actual-app/api requires a node version ${minimumNodeVersion}. Found that you are using: ${nodeVersion}. Please upgrade to a higher version What it means
@actual-app/api checks process.versions.node against the engines.node range from its package.json at init time. If the running Node version does not satisfy that range, init refuses to start. This prevents subtle breakage from unsupported Node runtimes.
Source
Thrown at packages/api/validateNodeVersion.ts:10
import { satisfies } from 'compare-versions';
import * as packageJson from './package.json';
export function validateNodeVersion(): void {
const nodeVersion = process.versions.node;
const minimumNodeVersion = packageJson.engines.node;
if (!satisfies(nodeVersion, minimumNodeVersion)) {
throw new Error(
`@actual-app/api requires a node version ${minimumNodeVersion}. Found that you are using: ${nodeVersion}. Please upgrade to a higher version`,
);
}
}
View on GitHub (pinned to d4334cb6e6)
Solutions
- Upgrade Node to a version matching the engines range shown in the message (e.g. nvm install 22 && nvm use 22).
- Update CI (GitHub Actions setup-node node-version) and Dockerfile base image to a supported Node.
- If truly necessary, bypass via api.init with the version check removed — not recommended; instead match the required Node.
Example fix
// before (CI workflow)
- uses: actions/setup-node@v4
with:
node-version: 18
// after
- uses: actions/setup-node@v4
with:
node-version: 22 Defensive patterns
Strategy: validation
Validate before calling
import { satisfies } from 'semver';
import packageJson from '@actual-app/api/package.json';
if (!satisfies(process.versions.node, packageJson.engines.node)) {
throw new Error(`Upgrade Node to ${packageJson.engines.node} before using @actual-app/api`);
} Type guard
null
Try / catch
try {
await api.init(config);
} catch (e) {
if (String(e.message).includes('requires a node version')) {
console.error(e.message);
process.exit(1); // fail fast with clear message in CI/deploys
}
throw e;
} Prevention
- Pin Node in CI via actions/setup-node with the version from engines.
- Use .nvmrc and run `nvm use` in shells and scripts.
- Use a Node base image matching engines.node in Dockerfiles.
- Add a preflight version check at script startup.
When it happens
Trigger: Running a script/app that calls api.init() on a Node version outside the supported range (e.g. Node 18/20 when engines requires >=22, or very new unreleased Node).
Common situations: CI runners pinned to an older Node; Docker images with stale base images; deploy servers with a system Node older than development; using nvm without selecting the right version.
Related errors
- Error importing budget: ${result.error}
- Error importing budget: no budget was loaded
- Error exporting budget: ${result.error}
- Error exporting budget: no data was returned
- Invalid ${source}: "${raw}". Expected "true", "false", "1",
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/45f57c45d749e596.
Report an issue: GitHub.