{"record":{"id":"63f6f2c9bbca104e","repo":"paperclipai/paperclip","slug":"unknown-config-key-warning-path-did-you-mean","errorCode":null,"errorMessage":"Unknown config key ${warning.path}; did you mean ${warning.suggestion}? It will be preserved.","messagePattern":"Unknown config key (.+?); did you mean (.+?)\\? It will be preserved\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/src/commands/configure.ts","lineNumber":104,"sourceCode":"  section?: string;\n}): Promise<void> {\n  printPaperclipCliBanner();\n  p.intro(pc.bgCyan(pc.black(\" paperclip configure \")));\n  const configPath = resolveConfigPath(opts.config);\n\n  if (!configExists(opts.config)) {\n    p.log.error(\"No config file found. Run `paperclipai onboard` first.\");\n    p.outro(\"\");\n    process.exitCode = 1;\n    return;\n  }\n\n  let config: PaperclipConfig;\n  let invalidBackupPath: string | undefined;\n  try {\n    config = readConfig(opts.config) ?? defaultConfig();\n    for (const warning of findPaperclipConfigKeyWarnings(config)) {\n      p.log.warn(`Unknown config key ${warning.path}; did you mean ${warning.suggestion}? It will be preserved.`);\n    }\n  } catch (err) {\n    const backupPath = backupInvalidConfig(opts.config);\n    p.log.warn(\n      `Existing config is invalid. Preserved the original bytes at ${backupPath}.\\n${err instanceof Error ? err.message : String(err)}`,\n    );\n\n    if (!process.stdin.isTTY || !process.stdout.isTTY) {\n      p.log.error(\n        `Refusing to replace ${configPath} without confirmation. Rerun interactively to repair from defaults; the original and ${backupPath} are unchanged.`,\n      );\n      p.outro(\"\");\n      process.exitCode = 1;\n      return;\n    }\n\n    const repair = await p.confirm({\n      message: `Repair from defaults? The invalid original is backed up at ${backupPath}.`,","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/cli/src/commands/configure.ts#L86-L122","documentation":"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.","triggerScenarios":"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.","commonSituations":"Manual edits of ~/.config/paperclip/config.json; downgrade/upgrade mismatches between CLI versions; copying config snippets from docs that use outdated key names.","solutions":["Rename the key at warning.path to warning.suggestion in the config file (both are printed in the message).","Remove the key entirely if it belongs to an old CLI version and nothing should consume it.","Run paperclipai configure and re-save so the file is rewritten from the current schema.","Regenerate a reference config via paperclipai onboard in a temp home and diff against yours to spot all drift at once."],"exampleFix":"// before (~/.config/paperclip/config.json)\n{\n  \"servr\": { \"port\": 3100 },\n  \"server\": { \"ports\": 3200 }\n}\n// warnings: Unknown config key servr; did you mean server?\n//           Unknown config key server.ports; did you mean server.port?\n\n// after\n{\n  \"server\": { \"port\": 3200 }\n}","handlingStrategy":"validation","validationCode":"import { findPaperclipConfigKeyWarnings, paperclipConfigSchema } from \"@paperclipai/shared\";\nconst config = JSON.parse(readFileSync(configPath, \"utf8\"));\nconst warnings = findPaperclipConfigKeyWarnings(config);\nif (warnings.length > 0) {\n  console.error(\"Fix config keys before proceeding:\", warnings);\n}","typeGuard":"const isConfigKeyWarning = (w: unknown): w is { path: string; suggestion: string } =>\n  typeof w === \"object\" && w !== null &&\n  typeof (w as { path?: unknown }).path === \"string\" &&\n  typeof (w as { suggestion?: unknown }).suggestion === \"string\";","tryCatchPattern":null,"preventionTips":["Prefer paperclipai configure/onboard over hand-editing config.json so keys always match the schema.","Validate configs with findPaperclipConfigKeyWarnings in CI when config files are templated.","After CLI upgrades, run configure once and review key-warnings for renamed options.","Never carry config files across CLI downgrades blindly."],"tags":["config","schema","typo","cli","configure"],"backgroundTag":"unknown-config-key","analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}