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

  1. Edit the config file so the offending key is a real JSON boolean: true or false, unquoted.
  2. Remove the key if you want the built-in default.
  3. 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

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


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