actualbudget/actual · error · Error
Invalid config file: key "${key}" must be a boolean, got ${t
Error message
Invalid config file: key "${key}" must be a boolean, got ${typeof v} What it means
validateConfigFileContent enforces that keys in booleanKeys hold actual JSON booleans. The error message includes the received typeof so you can see what was actually supplied. It is thrown while type-checking the config file content before it is merged into the resolved configuration.
Source
Thrown at packages/cli/src/config.ts:102
typeof v !== 'string'
) {
throw new Error(
`Invalid config file: key "${key}" must be a string, got ${typeof v}`,
);
}
if (
(numberKeys as readonly string[]).includes(key) &&
(typeof v !== 'number' || !Number.isInteger(v) || v < 0)
) {
throw new Error(
`Invalid config file: key "${key}" must be a non-negative integer`,
);
}
if (
(booleanKeys as readonly string[]).includes(key) &&
typeof v !== 'boolean'
) {
throw new Error(
`Invalid config file: key "${key}" must be a boolean, got ${typeof v}`,
);
}
}
return value as ConfigFileContent;
}
async function loadConfigFile(): Promise<ConfigFileContent> {
const explorer = cosmiconfig('actual', {
searchStrategy: 'global',
searchPlaces: [
'package.json',
'.actualrc',
'.actualrc.json',
'.actualrc.yaml',
'.actualrc.yml',
'actual.config.json',
'actual.config.yaml',View on GitHub (pinned to d4334cb6e6)
Solutions
- Edit the config file so the offending key is a real JSON boolean: true or false, unquoted.
- Remove the key if you want the built-in default.
- Search the config for quoted booleans ("true"/"false") to fix all occurrences at once.
Example fix
// before (config.json)
{ "verbose": "true" }
// after
{ "verbose": true } Defensive patterns
Strategy: validation
Validate before calling
function hasValidBooleans(cfg: Record<string, unknown>, booleanKeys: readonly string[]): boolean {
return booleanKeys.every(k => {
const v = cfg[k];
return v === undefined || typeof v === 'boolean';
});
} Type guard
function isBoolean(v: unknown): v is boolean {
return typeof v === 'boolean';
} Try / catch
try {
fileConfig = loadConfigFile(path);
} catch (err) {
if (err instanceof Error && /must be a boolean/.test(err.message)) {
const key = /key "([^"]+)"/.exec(err.message)?.[1];
console.error(`Fix ${key} in ${path}: it must be true or false (unquoted).`);
process.exit(1);
}
throw err;
} Prevention
- In JSON, write booleans as true/false — never "true"/"false" or 0/1.
- Generate config via a script using JSON.stringify to guarantee correct types.
- Grep config files for /"(true|false)"/ to catch quoted booleans.
- Validate the config against a schema before deployment.
When it happens
Trigger: A config file key listed in booleanKeys is set to a string like "true"/"false", or to a number 0/1, instead of a JSON true/false.
Common situations: Writing "verbose": "true" in JSON by hand; exporting env-style values into the config; generating the config with a tool that stringifies booleans.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid config file: expected an object with keys: ${configF
- Invalid config file: unknown key "${key}"
- Invalid config file: key "${key}" must be a string, got ${ty
- Invalid config file: key "${key}" must be a non-negative int
- Invalid id, must be string:
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/b27283a07ce594b8.
Report an issue: GitHub.