thedotmack/claude-mem · warning
[install] Failed to parse existing settings.json, starting…
Error message
[install] Failed to parse existing settings.json, starting from empty:
What it means
When writing Claude settings.json, the installer attempts to merge into the existing file. If the existing file cannot be parsed (corrupt JSON, BOM mishandling by older writers, truncated file), it warns and resets the document to an empty object, so existing settings in that file will be overwritten rather than merged.
Solutions
- Back up the file, fix or regenerate settings.json (validate it with `jq . settings.json`), then rerun the installer.
- If the settings are disposable, delete settings.json and let the installer recreate it from scratch.
- Restore settings.json from version control or a backup before reinstalling.
Example fix
// validate and repair before install jq . ~/.claude/settings.json || cp ~/.claude/settings.json.bak ~/.claude/settings.json
Defensive patterns
Strategy: try-catch
Validate before calling
try {
const parsed = JSON.parse(fs.readFileSync(settingsPath, 'utf-8').replace(/^\uFEFF/, ''));
console.log('settings.json is valid JSON');
} catch (e) {
console.warn('settings.json is corrupt; back it up before installing:', e.message);
} Type guard
function isSettingsObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
document = parseJsonWithBom(readFileSync(path, 'utf-8'));
} catch (parseError) {
console.warn('Failed to parse existing settings.json, starting from empty:', parseError.message);
document = {}; // back up the corrupt file first!
} Prevention
- Always back up settings.json before running install/update.
- Validate settings.json with `jq .` after any manual edit.
- Avoid killing the installer/worker mid-write; use editors that preserve UTF-8 without stray BOM.
When it happens
Trigger: `parseJsonWithBom(readFileSync(path, 'utf-8'))` throws for the settings.json at the target path — malformed JSON, encoding issues, or a partially written file from a crashed previous install.
Common situations: A previous install/update crashed mid-write leaving truncated JSON; manual hand-editing of settings.json introduced a syntax error; file saved with odd encoding/BOM by an editor.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- claude-mem: could not read
- Corrupt JSON in , refusing to overwrite user hooks
- Corrupt JSON in , refusing to overwrite user settings
- [install] Failed to read existing plugin version:
- Anthropic API error
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/5b2b77e4dceae201.
Report an issue: GitHub.
Appendix: source
Thrown at src/npx-cli/commands/install.ts:854
// apiKeyHelper, model, statusLine, etc.). readFlatSettings unwraps the
// env subtree for reads, but writing that flattened view back as the
// entire file silently drops every non-env top-level key — destroying
// user configuration that disableClaudeAutoMemory + writeJsonFileAtomic
// had carefully written.
//
// Track whether the file uses the env-nested shape so we mutate only the
// relevant subtree and preserve every other top-level key on write.
let document: Record<string, unknown> = {};
let envNested = false;
if (existsSync(path)) {
try {
const parsed = parseJsonWithBom(readFileSync(path, 'utf-8'));
if (parsed && typeof parsed === 'object') {
document = parsed as Record<string, unknown>;
envNested = typeof document.env === 'object' && document.env !== null;
}
} catch (parseError: unknown) {
console.warn('[install] Failed to parse existing settings.json, starting from empty:', parseError instanceof Error ? parseError.message : String(parseError));
document = {};
}
} else {
const dir = dirname(path);
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
}
const target = envNested
? (document.env as Record<string, unknown>)
: document;
for (const [key, value] of Object.entries(updates)) {
target[key] = value;
}
writeSettingsJsonAtomic(path, document);
// settings.json can carry tokens (CMEM Pro setup token, provider APIView on GitHub (pinned to d8bc9755e7)