paperclipai/paperclip · warning

Unknown config key ${warning.path}; did you mean ${warning.s

Error message

Unknown config key ${warning.path}; did you mean ${warning.suggestion}? It will be preserved.

What it means

paperclipai configure parses the config file successfully, then findPaperclipConfigKeyWarnings walks the parsed object against paperclipConfigSchema. Any key not present in the schema gets a nearest-match suggestion computed by edit distance (shared/src/config-schema.ts nearMatch), e.g. 'servr' -> 'server' or 'server.ports' -> 'server.port'. The unknown key is preserved on write, not dropped — this is a compatibility warning, not a parse failure.

Source

Thrown at cli/src/commands/configure.ts:104

  section?: string;
}): Promise<void> {
  printPaperclipCliBanner();
  p.intro(pc.bgCyan(pc.black(" paperclip configure ")));
  const configPath = resolveConfigPath(opts.config);

  if (!configExists(opts.config)) {
    p.log.error("No config file found. Run `paperclipai onboard` first.");
    p.outro("");
    process.exitCode = 1;
    return;
  }

  let config: PaperclipConfig;
  let invalidBackupPath: string | undefined;
  try {
    config = readConfig(opts.config) ?? defaultConfig();
    for (const warning of findPaperclipConfigKeyWarnings(config)) {
      p.log.warn(`Unknown config key ${warning.path}; did you mean ${warning.suggestion}? It will be preserved.`);
    }
  } catch (err) {
    const backupPath = backupInvalidConfig(opts.config);
    p.log.warn(
      `Existing config is invalid. Preserved the original bytes at ${backupPath}.\n${err instanceof Error ? err.message : String(err)}`,
    );

    if (!process.stdin.isTTY || !process.stdout.isTTY) {
      p.log.error(
        `Refusing to replace ${configPath} without confirmation. Rerun interactively to repair from defaults; the original and ${backupPath} are unchanged.`,
      );
      p.outro("");
      process.exitCode = 1;
      return;
    }

    const repair = await p.confirm({
      message: `Repair from defaults? The invalid original is backed up at ${backupPath}.`,

View on GitHub (pinned to 120ae5428f)

Solutions

  1. Rename the key at warning.path to warning.suggestion in the config file (both are printed in the message).
  2. Remove the key entirely if it belongs to an old CLI version and nothing should consume it.
  3. Run paperclipai configure and re-save so the file is rewritten from the current schema.
  4. Regenerate a reference config via paperclipai onboard in a temp home and diff against yours to spot all drift at once.

Example fix

// before (~/.config/paperclip/config.json)
{
  "servr": { "port": 3100 },
  "server": { "ports": 3200 }
}
// warnings: Unknown config key servr; did you mean server?
//           Unknown config key server.ports; did you mean server.port?

// after
{
  "server": { "port": 3200 }
}
Defensive patterns

Strategy: validation

Validate before calling

import { findPaperclipConfigKeyWarnings, paperclipConfigSchema } from "@paperclipai/shared";
const config = JSON.parse(readFileSync(configPath, "utf8"));
const warnings = findPaperclipConfigKeyWarnings(config);
if (warnings.length > 0) {
  console.error("Fix config keys before proceeding:", warnings);
}

Type guard

const isConfigKeyWarning = (w: unknown): w is { path: string; suggestion: string } =>
  typeof w === "object" && w !== null &&
  typeof (w as { path?: unknown }).path === "string" &&
  typeof (w as { suggestion?: unknown }).suggestion === "string";

Prevention

When it happens

Trigger: Hand-editing the Paperclip config with a typo; a key renamed or removed in a newer CLI version; config produced by a newer CLI then read by an older one; nesting a key under the wrong section.

Common situations: Manual edits of ~/.config/paperclip/config.json; downgrade/upgrade mismatches between CLI versions; copying config snippets from docs that use outdated key names.

Related errors


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/63f6f2c9bbca104e. Report an issue: GitHub.