toeverything/AFFiNE · error · Error

A config file path is required

Error message

A config file path is required

What it means

Thrown by ImportConfigCommand.execute(path?) — the 'data import-config' CLI command — when no path argument was supplied. The command needs a JSON config file to read overrides from, so an undefined path is a usage error.

Solutions

  1. Pass the config file path: run the import command with the JSON file as its argument (absolute or cwd-relative path).
  2. Check 'node cli.js data --help' (or the command help) for the exact argument position of the path.
  3. Ensure the path has no unquoted spaces breaking it into multiple argv entries.

Example fix

// before
$ node cli.js data import-config
// after
$ node cli.js data import-config ./config-overrides.json
Defensive patterns

Strategy: validation

Validate before calling

// In a CLI wrapper, check argv before invoking the command
const path = argv._[1];
assert(typeof path === 'string' && path.length > 0, 'config file path is required');
await importConfigCommand.execute(path);

Prevention

When it happens

Trigger: Running the server CLI import command without the config file path argument, e.g. 'node cli.js data import-config' with nothing after it.

Common situations: Wrong CLI subcommand spelling so the path is parsed as another flag; shell script omitted the argument; copy-pasted docs example without filling in the path.

Understand the failure class

Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/4b20e1354db5a1cd. Report an issue: GitHub.

Appendix: source

Thrown at packages/backend/server/src/data/commands/import.ts:20

import { resolve } from 'node:path';

import { Injectable, Logger } from '@nestjs/common';

import { ConfigFactory, InvalidAppConfigInput } from '../../base';
import { Models } from '../../models';

@Injectable()
export class ImportConfigCommand {
  logger = new Logger(ImportConfigCommand.name);

  constructor(
    private readonly models: Models,
    private readonly configFactory: ConfigFactory
  ) {}

  async execute(path?: string): Promise<void> {
    if (!path) {
      throw new Error('A config file path is required');
    }

    path = resolve(process.cwd(), path);

    const overrides: Record<string, Record<string, any>> = JSON.parse(
      readFileSync(path, 'utf-8')
    );

    const forValidation: { module: string; key: string; value: any }[] = [];
    const forSaving: { key: string; value: any }[] = [];
    Object.entries(overrides).forEach(([module, config]) => {
      if (module === '$schema') {
        return;
      }

      Object.entries(config).forEach(([key, value]) => {
        forValidation.push({
          module,

View on GitHub (pinned to b4c8548c09)