Skip to content

fix(cli): an unreadable registry says so instead of crashing - #787

Merged
blafourcade merged 1 commit into
nextfrom
fix/an-unreadable-registry-says-so
Sep 6, 2026
Merged

fix(cli): an unreadable registry says so instead of crashing#787
blafourcade merged 1 commit into
nextfrom
fix/an-unreadable-registry-says-so

Conversation

@blafourcade

Copy link
Copy Markdown
Contributor

What

aidd marketplace list died with

Error: Cannot read properties of undefined (reading 'map')

on a ~/.config/aidd/marketplaces.json holding {"version":1} — a real file, found while clearing test residue out of a machine's own configuration.

MarketplaceRegistryAdapter.read caught a missing file and nothing else. JSON.parse could throw, and parsed.marketplaces could be undefined, so a present-but-malformed registry reached .map() and produced a stack trace naming nothing a person can act on. Invalid JSON gave the same shape of answer, in the parser's words rather than the tool's.

Why not read it as empty

That would be worse than crashing. save() reads this same list, appends to it and writes the whole file back — so one silent empty read turns a file with five marketplaces into a file with one.

A missing file is a different answer and keeps its own: no file, no marketplaces, nothing to lose.

Behaviour, verified on the built binary

marketplaces.json before after
absent No marketplaces registered. unchanged
{"version":1,"marketplaces":[]} No marketplaces registered. unchanged
{"version":1} Cannot read properties of undefined (reading 'map') Cannot read the marketplace registry at <path>: it carries no \marketplaces` list. Repair the file, or delete it to start from an empty registry.`
not json Unexpected token 'o', "not json" is not valid JSON same sentence, the parser's reason inside it, the path named

Tests

Three added to marketplace-registry-adapter.integration.test.ts. The two for the malformed states were red first, for the reason they name:

→ expected [Function] to throw error including '/var/folders/…/marketplaces.json'
  but got 'Cannot read properties of undefined (…'
→ expected [Function] to throw error including '/var/folders/…/marketplaces.json'
  but got 'Unexpected token \'o\', "not json" is…'

The third — a present, empty list still reading as an empty registry — passed before and after, and is there so the fix cannot be mistaken for "any unusual file is an error".

Gates

  • cli vitest — 3507/3507
  • node --test "scripts/__tests__/**/*.test.js" — 380/380
  • knip --production --exclude exports,types — exit 0
  • biome check src tests — the only two warnings are pre-existing, in a file this branch does not touch

🤖 Generated with Claude Code

https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp

@blafourcade
blafourcade requested a review from a team as a code owner September 6, 2026 06:30
`aidd marketplace list` died with

    Error: Cannot read properties of undefined (reading 'map')

on a `~/.config/aidd/marketplaces.json` holding `{"version":1}` — a real file,
found while clearing test residue out of a machine's own configuration. The
reader caught a missing file and nothing else: `JSON.parse` could throw, and
`parsed.marketplaces` could be undefined, so a present-but-malformed registry
reached `.map()` and produced a stack trace naming nothing a person can act
on. Invalid JSON gave the same shape of answer, in the parser's words rather
than the tool's.

Reading such a file as an empty registry would be worse than crashing.
`save()` reads this same list, appends to it and writes the whole file back,
so one silent empty read turns a file with five marketplaces into a file with
one. A missing file is a different answer and keeps its own: no file, no
marketplaces, nothing to lose.

So a file that exists but cannot supply the list is refused by name:

    Cannot read the marketplace registry at <path>: it carries no
    `marketplaces` list. Repair the file, or delete it to start from an empty
    registry.

Verified on the built binary across all four states — no file and an empty
`marketplaces: []` both answer "No marketplaces registered."; a missing list
and invalid JSON each name the file and the reason.

The bundle budget rises 601 -> 603 KB, measured 600.7 -> 601.2 KB. The
guard's own comment asks for exactly that: the budget makes growth visible
rather than walling it off, and a raise is what a reviewer sees. This one is
the smallest so far, and it is the raise that showed the budget had 0.3 KB of
headroom left — less than a correctness fix costs. It keeps the same 2.2 KB
headroom as the four raises before it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
@blafourcade
blafourcade force-pushed the fix/an-unreadable-registry-says-so branch from 91c1308 to 1b4a480 Compare September 6, 2026 06:36
@blafourcade

Copy link
Copy Markdown
Contributor Author

Rebuilt after CI: the three red jobs were all one failure — pnpm build running check-bundle-size.mjs before the tests.

Bundle size: 601.3 KB / budget: 601 KB
FAIL: bundle exceeds budget (601.3 KB > 601 KB)

Measured on this branch: next builds at 600.7 KB against a 601 KB budget — 0.3 KB of headroom, less than this fix costs.

Trimmed what could be trimmed first (the named error class became a plain Error from a helper: 601.3 → 601.2 KB), then raised the budget to 603 KB and recorded the measurement in the script's own ledger, the way the four raises before it did. Its comment asks for exactly that: "The budget exists to make growth visible, not to be a wall: it is raised deliberately when a feature earns it, and the raise is what a reviewer sees."

Green locally: 3507/3507 cli, 380/380 scripts, knip exit 0, biome clean, OK: within budget.

@blafourcade
blafourcade merged commit 25f0837 into next Sep 6, 2026
17 checks passed
@blafourcade
blafourcade deleted the fix/an-unreadable-registry-says-so branch September 6, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant