Global settings.json corrupted into a top-level JSON array (5 partial snapshots) instead of an object
Bug description
My global ~/.claude/settings.json (Windows) ended up as a top-level JSON array with 5 elements, instead of the expected top-level object. This caused Claude Code to fail settings validation on startup with:
Settings (C:\Users\<user>\.claude\settings.json): Expected object, but received array
What the array contained
Each of the 5 array elements looked like a progressively more complete snapshot of the same intended settings object — as if 5 separate partial writes were appended to an array instead of being merged into (or overwriting) the existing object:
{"source": "github", "repo": "<org>/ai-plugins"}{"source": {"source": "github", "repo": "<org>/ai-plugins"}}{"<marketplace-1>": {"source": {...}}, "<marketplace-2>": {"source": {...}}}{"<plugin-1>@<marketplace-1>": true, "<plugin-2>@<marketplace-2>": true}- The final, complete object:
enabledPlugins,extraKnownMarketplaces,autoUpdatesChannel,tui,skipDangerousModePermissionPrompt,theme— a full superset of elements 1–4.
Why I don't think this is our own tooling's fault
We have an internal bootstrap script that adds a plugin marketplace + enables a plugin in ~/.claude/settings.json. I reviewed it: it reads the existing file, deep-merges a JSON object patch into it, and writes the merged object back — never an array, and never at the top level. One of the two marketplaces present in the corrupted array (microsoft/azure-skills) isn't even referenced by that script, so at least one of the 5 snapshots must have come from a separate action (most likely a manual /plugin marketplace add / /plugin install in a Claude Code session).
The shape of the corruption (5 non-atomic, increasingly-complete snapshots of the same object, wrapped in an array) looks like it originated from Claude Code's own internal settings-writer used by the plugin/marketplace install flow — possibly a race or interrupted-write condition when multiple plugin-management operations touched settings.json in close succession (e.g. a manual /plugin marketplace add overlapping with an external script also writing to the same file).
Environment
- OS: Windows 11
- Claude Code: latest (auto-update channel)
Impact
Claude Code refused to load the settings file at all until manually fixed (had to hand-reconstruct the intended object from the array's last element).
Suggested fix
Whatever internal path writes to settings.json during plugin/marketplace install operations should validate that the file is (or becomes) a top-level object, and should merge into the existing object atomically rather than potentially appending/wrapping in an array.