ruvnet/ruflo · warning · Error

Config file already exists

Error message

Config file already exists: ${targetPath}. Use --force to overwrite.

What it means

ConfigFileManager.create(cwd, overrides?, force?) refuses to clobber an existing config file: it resolves cwd/claude-flow.config.json (CONFIG_FILENAMES[0]) and, if that path already exists and force was not passed as true, throws with a pointer to use --force. This protects existing settings from being reset to { ...DEFAULT_CONFIG, ...overrides } by a re-run of init.

Solutions

  1. If you only want to change values, use set(cwd, key, value) instead of create() — it merges into the existing file
  2. If you truly want defaults again, pass force: manager.create(cwd, overrides, true) (CLI: --force), after backing up the current file
  3. Otherwise, detect the existing file first with fs.existsSync and skip creation

Example fix

// before
manager.create(cwd, { swarm: { topology: 'mesh' } }); // repo already has claude-flow.config.json -> throws

// after
if (fs.existsSync(path.join(cwd, 'claude-flow.config.json'))) {
  manager.set(cwd, 'swarm.topology', 'mesh'); // merge into existing
} else {
  manager.create(cwd, { swarm: { topology: 'mesh' } });
}
Defensive patterns

Strategy: validation

Validate before calling

const configPath = path.join(cwd, 'claude-flow.config.json'); // CONFIG_FILENAMES[0]
if (fs.existsSync(configPath)) {
  manager.set(cwd, 'some.key', value); // merge, don't clobber
} else {
  manager.create(cwd, overrides);
}

Type guard

const configExists = (cwd: string): boolean => fs.existsSync(path.join(cwd, 'claude-flow.config.json'));

Try / catch

try {
  manager.create(cwd, overrides);
} catch (e) {
  if (e instanceof Error && e.message.includes('Use --force to overwrite')) {
    manager.set(cwd, 'key', value); // or create(cwd, overrides, true) after backing up
  } else throw e;
}

Prevention

When it happens

Trigger: Running project init twice (e.g. `claude-flow init` re-run in an already-initialized repo), automated scaffolding scripts that call create() on every run, or a CI bootstrap step hitting a repo where claude-flow.config.json is committed.

Common situations: Re-running a setup wizard after a partial failure where the file was already written, template generators that initialize the config unconditionally, onboarding scripts for new team members run in a cloned repo that already ships config.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/2695e803bdeafd62. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/services/config-file-manager.ts:125

    const config = this.getConfig(cwd);
    return getNestedValue(config, key);
  }

  /** Set a nested config value by dot-separated key */
  set(cwd: string, key: string, value: unknown): void {
    const config = this.getConfig(cwd);
    setNestedValue(config, key, value);
    this.config = config;
    const targetPath = this.configPath ?? path.resolve(cwd, CONFIG_FILENAMES[0]);
    this.writeAtomic(targetPath, config);
    this.configPath = targetPath;
  }

  /** Create a new config file with defaults */
  create(cwd: string, overrides?: Record<string, unknown>, force?: boolean): string {
    const targetPath = path.resolve(cwd, CONFIG_FILENAMES[0]);
    if (fs.existsSync(targetPath) && !force) {
      throw new Error(`Config file already exists: ${targetPath}. Use --force to overwrite.`);
    }
    const config = { ...DEFAULT_CONFIG, ...overrides };
    this.writeAtomic(targetPath, config);
    this.config = config;
    this.configPath = targetPath;
    return targetPath;
  }

  /** Reset config to defaults */
  reset(cwd: string): string {
    const targetPath = this.configPath ?? path.resolve(cwd, CONFIG_FILENAMES[0]);
    this.writeAtomic(targetPath, DEFAULT_CONFIG);
    this.config = { ...DEFAULT_CONFIG };
    this.configPath = targetPath;
    return targetPath;
  }

  /** Export config to a specific path */

View on GitHub (pinned to fa13ee4ad6)