musistudio/claude-code-router · error · Error

Refusing to archive unknown legacy JSON config file: ${unsup

Error message

Refusing to archive unknown legacy JSON config file: ${unsupportedFiles.join(", ")}

What it means

archiveLegacyJsonConfigFiles only allows archiving files on its known legacyJsonConfigFiles list; anything else is refused to prevent accidentally archiving unknown/critical config.

Source

Thrown at packages/core/src/config/config-repository.ts:131

  async replaceConfigSnapshot(value: unknown, apiKeys: ApiKeyConfig[]): Promise<ApiKeyConfig[]> {
    const normalized = uniqueApiKeyConfigs(apiKeys);
    const database = await this.getDatabase();
    runTransaction(database, () => {
      replaceAppConfigRow(database, appConfigKey, value);
      replaceApiKeyRows(database, normalized);
    });
    secureDatabaseFilePermissions(this.dbFile);
    return normalized;
  }

  async archiveLegacyJsonConfigFiles(files: string[]): Promise<void> {
    const requestedFiles = uniquePaths(files);
    const unsupportedFiles = requestedFiles.filter(
      (file) => !legacyJsonConfigFiles.some((candidate) => samePath(candidate, file))
    );
    if (unsupportedFiles.length > 0) {
      throw new Error(`Refusing to archive unknown legacy JSON config file: ${unsupportedFiles.join(", ")}`);
    }
    if (requestedFiles.length === 0) {
      return;
    }
    const database = await this.getDatabase();
    archiveAndRemoveFiles(database, requestedFiles, "legacy-json-config", this.removeFile);
  }

  private async getDatabase(): Promise<SqlDatabase> {
    if (this.database) {
      return this.database;
    }
    this.initPromise ??= this.open();
    return this.initPromise;
  }

  private async open(): Promise<SqlDatabase> {
    const dbDir = dirname(this.dbFile);

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Only pass paths that appear in legacyJsonConfigFiles.
  2. If a new legacy file should be archivable, add it to the legacyJsonConfigFiles allowlist in config-repository.ts.
  3. Normalize path separators/case before calling.
Defensive patterns

Strategy: validation

Validate before calling

const allowed = legacyJsonConfigFiles;
const safe = files.filter(f => allowed.some(a => samePath(a, f)));
if (safe.length !== files.length) rejectUnknown(files);

Type guard

function isLegacyJsonConfigFile(f: string): boolean {
  return legacyJsonConfigFiles.some(c => samePath(c, f));
}

Prevention

When it happens

Trigger: Passing a file path that doesn't samePath-match any entry in legacyJsonConfigFiles.

Common situations: Caller constructs the file list from user input or a newer config schema; case/separator differences on Windows defeating samePath; renamed legacy files.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/a05ebe745655e5fa. Report an issue: GitHub.