Skip to content

fix(validate-plugin): report malformed plugin.json/marketplace.json as validation errors - #206

Merged
zircote merged 2 commits into
mainfrom
fix/182-validate-plugin-manifest-parse-guard
Aug 4, 2026
Merged

zircote merged 2 commits into
mainfrom
fix/182-validate-plugin-manifest-parse-guard

Conversation

@zircote

@zircote zircote commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

A JSON syntax error in .claude-plugin/plugin.json or .claude-plugin/marketplace.json threw an unhandled SyntaxError and terminated scripts/validate-plugin.mjs with a Node stack trace, instead of pushing a structured entry onto errors[] and reporting it through the gate's normal VALIDATION FAILED: path. The .mcp.json read in section 3 already guards its readJson() call; this extends the identical try/catch pattern to the other two manifest reads, so every manifest parse failure is reported alongside any other findings in the same run.

Changes

  • scripts/validate-plugin.mjs: wrap the plugin.json (section 1) and marketplace.json (section 2) reads in try/catch, appending the parse message to errors[] — matching section 3's existing pattern.
  • scripts/validate-plugin.mjs: add a VALIDATE_PLUGIN_ROOT env test hook so the test suite can point the validator at a fixture plugin root instead of this repository itself.
  • tests/validate-plugin-manifest-parse.test.mjs: regression tests — a valid fixture root passes; a malformed plugin.json and a malformed marketplace.json each produce a structured VALIDATION FAILED: entry (exit 1, no stack trace); and both parse failures aggregate in one run instead of the first aborting the script. All four fail against the pre-fix script and pass with it.

Verification

  • npm run test:hook — 273/273 pass (after npm run hydrate-schema, as CI does)
  • npm run validate-plugin — OK, 0 errors
  • npm run lint:md — 0 issues

Closes #182

…s validation errors

A JSON syntax error in .claude-plugin/plugin.json or
.claude-plugin/marketplace.json threw an unhandled SyntaxError and killed
the gate with a stack trace instead of flowing through errors[] like the
sibling .mcp.json read already does. Wrap both reads in the same
try/catch pattern so every manifest parse failure lands in the
VALIDATION FAILED report, aggregated with any other findings.

Adds a VALIDATE_PLUGIN_ROOT test hook so the regression tests can point
the validator at fixture roots with deliberately malformed manifests.

Closes #182

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes scripts/validate-plugin.mjs so malformed JSON in .claude-plugin/plugin.json or .claude-plugin/marketplace.json is reported as a structured validation error (aggregated in errors[]) instead of crashing with an unhandled SyntaxError, and adds regression tests to lock that behavior in.

Changes:

  • Wrap readJson() calls for plugin.json and marketplace.json in try/catch and append parse failures to errors[].
  • Add a VALIDATE_PLUGIN_ROOT environment-variable hook to allow running the validator against a fixture root (for tests).
  • Add subprocess-based regression tests covering single and aggregated manifest parse failures.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
scripts/validate-plugin.mjs Adds guarded JSON parsing for manifests and introduces the VALIDATE_PLUGIN_ROOT hook used by tests.
tests/validate-plugin-manifest-parse.test.mjs Adds regression coverage ensuring malformed manifests are reported via VALIDATION FAILED: without stack traces and with aggregation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/validate-plugin.mjs
The test hook read the override with `??`, which only falls back on
null/undefined. An exported-but-empty VALIDATE_PLUGIN_ROOT therefore set
ROOT to "", making every manifest path cwd-relative: the gate validated
whatever happened to be in the working directory instead of this plugin.
The failure is cwd-dependent and so intermittent — run from the repo root
it passes by accident, run from anywhere else it reports a spurious
".claude-plugin/plugin.json: missing".

Read the override with `||` instead, matching how every other env
override in this codebase is read (strOrNull in lib/provenance-ledger.mjs,
the CLAUDE_CONFIG_DIR guard in lib/provenance-config.mjs, and
process.env.PATH in lib/doctor.mjs).

Adds a regression test that spawns the validator from a temp cwd with the
override set to "" and asserts it still resolves this repository. The temp
cwd is load-bearing: with cwd at the repo root the test passes either way.
Copilot AI review requested due to automatic review settings August 4, 2026 15:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tests/validate-plugin-manifest-parse.test.mjs:56

  • This assertion couples the test to the repository's current plugin name ("mif-docs"), which makes the test brittle if the manifest name ever changes. The test goal (empty VALIDATE_PLUGIN_ROOT falls back to repo root, not temp cwd) is already demonstrated by a successful exit status; if you want an additional stdout assertion, prefer something invariant like the reported error count.
    assert.match(r.stdout, /plugin: mif-docs/);

@zircote
zircote merged commit e7494d3 into main Aug 4, 2026
13 checks passed
@zircote
zircote deleted the fix/182-validate-plugin-manifest-parse-guard branch August 4, 2026 16:28
@zircote zircote mentioned this pull request Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

validate-plugin: malformed plugin.json or marketplace.json crashes instead of reporting a validation error

2 participants