paperclipai/paperclip · error · Error
Invalid config at ${filePath}: ${formatValidationError(parse
Error message
Invalid config at ${filePath}: ${formatValidationError(parsed.error)} What it means
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.
Source
Thrown at cli/src/config/store.ts:98
.map((issue) => {
const pathParts = Array.isArray(issue.path) ? issue.path.map(String) : [];
const issuePath = pathParts.length > 0 ? pathParts.join(".") : "config";
const message = typeof issue.message === "string" ? issue.message : "Invalid value";
return `${issuePath}: ${message}`;
})
.join("; ");
}
return err instanceof Error ? err.message : String(err);
}
export function readConfig(configPath?: string): PaperclipConfig | null {
const filePath = resolveConfigPath(configPath);
if (!fs.existsSync(filePath)) return null;
const raw = parseJson(filePath);
const migrated = migrateLegacyConfig(raw);
const parsed = paperclipConfigSchema.safeParse(migrated);
if (!parsed.success) {
throw new Error(`Invalid config at ${filePath}: ${formatValidationError(parsed.error)}`);
}
return parsed.data;
}
function effectiveConfig(config: PaperclipConfig): Record<string, unknown> {
const meta = { ...config.$meta } as Record<string, unknown>;
delete meta.updatedAt;
delete meta.source;
return {
...config,
$meta: meta,
};
}
function syncDirectory(directoryPath: string): void {
let directoryDescriptor: number | null = null;
try {
directoryDescriptor = fs.openSync(directoryPath, "r");View on GitHub (pinned to 67001ec6eb)
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.
Example fix
// before: config.json has { "database": { "mode": "postgrs" } } (typo, enum violation)
// after: config.json has { "database": { "mode": "embedded-postgres" } } Defensive patterns
Strategy: validation
Validate before calling
import { paperclipConfigSchema } from "./schema.js";
import fs from "node:fs";
function safeReadConfig(filePath: string) {
if (!fs.existsSync(filePath)) return null;
const raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
const parsed = paperclipConfigSchema.safeParse(raw);
if (!parsed.success) {
for (const issue of parsed.error.issues) {
console.error(`${issue.path.join(".")}: ${issue.message}`);
}
return null; // or prompt user to fix
}
return parsed.data;
} Type guard
import { paperclipConfigSchema, type PaperclipConfig } from "./schema.js";
function isPaperclipConfig(value: unknown): value is PaperclipConfig {
return paperclipConfigSchema.safeParse(value).success;
} Try / catch
import { readConfig } from "./config/store.js";
let config;
try {
config = readConfig(configPath);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Invalid config at")) {
console.error("Config validation failed:", err.message);
// surface field-level issues to the user, offer to reset
process.exit(1);
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
- Failed to parse JSON at ${filePath}: ${err instanceof Error
- --payload must be a JSON object
- ${name} must be a JSON object
- Invalid ${name} JSON: ${err instanceof Error ? err.message :
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/aacfe94902f4142b.
Report an issue: GitHub.