{"record":{"id":"aacfe94902f4142b","repo":"paperclipai/paperclip","slug":"invalid-config-at-filepath-formatvalidatione","errorCode":null,"errorMessage":"Invalid config at ${filePath}: ${formatValidationError(parsed.error)}","messagePattern":"Invalid config at (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/config/store.ts","lineNumber":98,"sourceCode":"      .map((issue) => {\n        const pathParts = Array.isArray(issue.path) ? issue.path.map(String) : [];\n        const issuePath = pathParts.length > 0 ? pathParts.join(\".\") : \"config\";\n        const message = typeof issue.message === \"string\" ? issue.message : \"Invalid value\";\n        return `${issuePath}: ${message}`;\n      })\n      .join(\"; \");\n  }\n  return err instanceof Error ? err.message : String(err);\n}\n\nexport function readConfig(configPath?: string): PaperclipConfig | null {\n  const filePath = resolveConfigPath(configPath);\n  if (!fs.existsSync(filePath)) return null;\n  const raw = parseJson(filePath);\n  const migrated = migrateLegacyConfig(raw);\n  const parsed = paperclipConfigSchema.safeParse(migrated);\n  if (!parsed.success) {\n    throw new Error(`Invalid config at ${filePath}: ${formatValidationError(parsed.error)}`);\n  }\n  return parsed.data;\n}\n\nfunction effectiveConfig(config: PaperclipConfig): Record<string, unknown> {\n  const meta = { ...config.$meta } as Record<string, unknown>;\n  delete meta.updatedAt;\n  delete meta.source;\n  return {\n    ...config,\n    $meta: meta,\n  };\n}\n\nfunction syncDirectory(directoryPath: string): void {\n  let directoryDescriptor: number | null = null;\n  try {\n    directoryDescriptor = fs.openSync(directoryPath, \"r\");","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/config/store.ts#L80-L116","documentation":"Thrown by readConfig() after the on-disk config file at the resolved path is successfully read as JSON but fails validation against paperclipConfigSchema (a Zod schema). The config may also have passed through migrateLegacyConfig() first, which only rewrites legacy pglite database fields. The error message includes the file path and a formatted list of every Zod issue (path + message) joined by semicolons, so the developer can see exactly which fields are wrong.","triggerScenarios":"Called readConfig(configPath?) where the resolved file exists and is valid JSON, but at least one field violates the schema (wrong type, unknown key under strict mode, missing required field, enum mismatch, out-of-range number). The schema is parsed via paperclipConfigSchema.safeParse(migrated) and parsed.success is false.","commonSituations":"1) Hand-editing .paperclip/config.json and introducing a typo or wrong type (e.g. database.mode set to a string not in the enum). 2) Upgrading Paperclip CLI to a version that tightened or renamed config fields without updating the local config. 3) Leaving a legacy field that migrateLegacyConfig does not cover. 4) PASTE error leaving a trailing comma or malformed structure that still parses as JSON but with unexpected keys.","solutions":["Read the full error message: each 'path: message' segment names the exact config field and what it expects. Fix those fields in the file shown in the path.","Open the file at the reported filePath and correct each flagged field to match the schema types/enums.","If you have a legacy config (e.g. database.mode='pglite'), confirm migrateLegacyConfig covers your legacy key; if not, manually rename to the new key (e.g. 'embedded-postgres') and retry.","If the config is unrecoverable, back it up with backupInvalidConfig() and let the CLI write a fresh default config.","Validate the config programmatically before passing it in: run paperclipConfigSchema.safeParse() on the parsed object to get actionable issues early."],"exampleFix":"// before: config.json has { \"database\": { \"mode\": \"postgrs\" } }  (typo, enum violation)\n// after:  config.json has { \"database\": { \"mode\": \"embedded-postgres\" } }","handlingStrategy":"validation","validationCode":"import { paperclipConfigSchema } from \"./schema.js\";\nimport fs from \"node:fs\";\n\nfunction safeReadConfig(filePath: string) {\n  if (!fs.existsSync(filePath)) return null;\n  const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n  const parsed = paperclipConfigSchema.safeParse(raw);\n  if (!parsed.success) {\n    for (const issue of parsed.error.issues) {\n      console.error(`${issue.path.join(\".\")}: ${issue.message}`);\n    }\n    return null; // or prompt user to fix\n  }\n  return parsed.data;\n}","typeGuard":"import { paperclipConfigSchema, type PaperclipConfig } from \"./schema.js\";\n\nfunction isPaperclipConfig(value: unknown): value is PaperclipConfig {\n  return paperclipConfigSchema.safeParse(value).success;\n}","tryCatchPattern":"import { readConfig } from \"./config/store.js\";\n\nlet config;\ntry {\n  config = readConfig(configPath);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Invalid config at\")) {\n    console.error(\"Config validation failed:\", err.message);\n    // surface field-level issues to the user, offer to reset\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Validate config edits with paperclipConfigSchema before saving.","Run 'paperclipai config validate' (if available) after hand-editing config.json.","Keep config under version control so bad edits are revertible.","When upgrading the CLI, read release notes for renamed/removed config fields."],"tags":["config","validation","zod","schema","cli"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}