Skip to content

fix: use JSON5 fallback for plugin manifest parsing (#57734) [AI-assisted]#57784

Closed
singleGanghood wants to merge 1 commit into
openclaw:mainfrom
singleGanghood:fix/issue-57734-plugin-manifest-json-parse
Closed

fix: use JSON5 fallback for plugin manifest parsing (#57734) [AI-assisted]#57784
singleGanghood wants to merge 1 commit into
openclaw:mainfrom
singleGanghood:fix/issue-57734-plugin-manifest-json-parse

Conversation

@singleGanghood

Copy link
Copy Markdown
Contributor

fix: use JSON5 fallback for plugin manifest parsing (#57734) [AI-assisted]

Plugin installation fails with 'Config validation failed' when a third-party plugin's openclaw.plugin.json contains JSON5 syntax (trailing commas, comments, unquoted keys). Replace strict JSON.parse() with parseJsonWithJson5Fallback() in manifest.ts and bundle-manifest.ts to tolerate non-standard JSON in plugin manifests.

Summary

  • Problem: manifest.ts and bundle-manifest.ts use strict JSON.parse() to read plugin manifest files (openclaw.plugin.json). When a third-party plugin ships a manifest with JSON5 syntax (trailing commas, comments, unquoted property names), parsing fails with SyntaxError: Expected double-quoted property name in JSON at position 8912 (line 219 column 5), which propagates through manifest-registry.tsvalidation.tsio.ts and surfaces as Config validation failed.
  • Why it matters: Users cannot install any third-party plugin whose manifest contains even trivially non-standard JSON, making the plugin ecosystem less robust and the error message misleading (points to config validation rather than manifest parsing).
  • What changed: Replaced JSON.parse() with the existing project utility parseJsonWithJson5Fallback() (from src/utils/parse-json-compat.ts) in both manifest.ts and bundle-manifest.ts. This function first attempts standard JSON.parse() and, on failure, falls back to JSON5.parse(), tolerating trailing commas, comments, and unquoted keys.
  • What did NOT change (scope boundary): Config file writing (io.ts / JSON.stringify) is untouched — OpenClaw's own config output remains strict JSON. Only the reading of third-party plugin manifest files is relaxed.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause / Regression History (if applicable)

  • Root cause: manifest.ts:263 and bundle-manifest.ts:120 use strict JSON.parse() to parse plugin manifest files. The JSON spec does not allow trailing commas, comments, or unquoted keys, but many real-world tool ecosystems (VS Code extensions, TypeScript configs, etc.) commonly emit JSON5-compatible files. When @vectorize-io/hindsight-openclaw shipped an openclaw.plugin.json with such syntax, JSON.parse() threw a SyntaxError at line 219.
  • Missing detection / guardrail: No test existed that exercised manifest parsing with non-standard JSON input. The project already had parseJsonWithJson5Fallback() for config reading (src/utils/parse-json-compat.ts) but it was not applied to plugin manifest loading.
  • Prior context: The parseJsonWithJson5Fallback utility was introduced for config/io.ts to handle user-edited config files; plugin manifests were overlooked because they were assumed to always be machine-generated strict JSON.
  • Why this regressed now: Not a regression — this is a latent bug exposed when the first third-party plugin (@vectorize-io/hindsight-openclaw) published a manifest with trailing commas.
  • If unknown, what was ruled out: Config writing (JSON.stringify in io.ts:2185) was confirmed to always produce valid JSON — the issue is exclusively on the read path for plugin manifests.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/plugins/manifest.test.ts (new), src/plugins/bundle-manifest.test.ts (extended)
  • Scenario the test should lock in: loadPluginManifest and loadBundleManifest succeed when the manifest file contains trailing commas, single-line/block comments, or unquoted property names.
  • Why this is the smallest reliable guardrail: Unit tests directly exercise the JSON parsing boundary in the two affected functions without requiring a full plugin installation flow.
  • Existing test that already covers this: None previously — bundle-manifest.test.ts existed but only tested strict JSON inputs.

User-visible / Behavior Changes

  • Plugin installation now succeeds for plugins whose openclaw.plugin.json manifest contains JSON5-compatible syntax (trailing commas, comments, unquoted keys).
  • No change to config file output format (remains strict JSON).
  • No change to error messages for genuinely malformed manifests (both JSON.parse and JSON5.parse must fail for an error to surface).

Diagram (if applicable)

Before:
[plugin install] -> manifest.ts JSON.parse() -> SyntaxError -> manifest-registry diagnostic
  -> validation.ts config issue -> io.ts "Config validation failed" ✗

After:
[plugin install] -> manifest.ts parseJsonWithJson5Fallback()
  -> JSON.parse() fails -> JSON5.parse() succeeds -> manifest loaded ✓

@greptile-apps

greptile-apps Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes a minimal, targeted fix to replace JSON.parse() with the existing parseJsonWithJson5Fallback() utility in two plugin manifest-loading functions (manifest.ts and bundle-manifest.ts). This allows third-party plugin manifests written with JSON5-compatible syntax (trailing commas, comments, unquoted keys) to be parsed successfully, resolving the Config validation failed error that surfaced from @vectorize-io/hindsight-openclaw.

Key changes:

  • src/plugins/manifest.ts and src/plugins/bundle-manifest.ts: JSON.parse() replaced with parseJsonWithJson5Fallback() — the utility already in use for config file reading (src/utils/parse-json-compat.ts). Error handling, file-descriptor cleanup, and validation logic are entirely unchanged.
  • src/plugins/manifest.test.ts (new): Adds full unit coverage for loadPluginManifest, including success paths for strict JSON and each JSON5 extension (trailing commas, single-line comments, block comments, unquoted keys), and error paths for a missing manifest, truly invalid syntax, a non-object manifest, a missing id, and a missing configSchema.
  • src/plugins/bundle-manifest.test.ts: Extended with three parallel JSON5 tests for loadBundleManifest.

The change is well-scoped: only the read path for third-party plugin manifests is relaxed; config-file output (JSON.stringify in io.ts) is untouched.

Confidence Score: 5/5

Safe to merge — the fix is minimal, the utility is already battle-tested in the config read path, and new tests cover all JSON5 extensions plus error cases.

No logic errors, no security concerns, no missing error-handling paths. Both file descriptors are still closed in finally blocks. The parseJsonWithJson5Fallback utility tries standard JSON.parse first (performance unchanged for well-formed manifests) and only falls back to JSON5.parse on failure. All remaining review findings are P2 or lower.

No files require special attention.

Important Files Changed

Filename Overview
src/plugins/manifest.ts Single-line swap of JSON.parse for parseJsonWithJson5Fallback; error handling and fd cleanup unchanged.
src/plugins/bundle-manifest.ts Same single-line swap; try/catch/finally structure preserved correctly.
src/plugins/manifest.test.ts New test file covering all JSON5 extensions and every error path for loadPluginManifest.
src/plugins/bundle-manifest.test.ts Extended with three JSON5 fallback tests (trailing commas, comments, unquoted keys) for loadBundleManifest.

Reviews (1): Last reviewed commit: "fix: use JSON5 fallback for plugin manif..." | Re-trigger Greptile

@singleGanghood singleGanghood changed the title fix: use JSON5 fallback for plugin manifest parsing (#57734) [AI-assi… fix: use JSON5 fallback for plugin manifest parsing (#57734) [AI-assisted] Mar 31, 2026
@singleGanghood singleGanghood force-pushed the fix/issue-57734-plugin-manifest-json-parse branch 3 times, most recently from 25111aa to e0e52be Compare March 31, 2026 08:50
…[AI-assisted]

Plugin installation fails with 'Config validation failed' when a third-party plugin's openclaw.plugin.json contains JSON5 syntax (trailing commas, comments, unquoted keys). Replace strict JSON.parse() with parseJsonWithJson5Fallback() in manifest.ts and bundle-manifest.ts to tolerate non-standard JSON in plugin manifests.
@singleGanghood singleGanghood force-pushed the fix/issue-57734-plugin-manifest-json-parse branch from e0e52be to ef9a064 Compare March 31, 2026 13:37
@singleGanghood singleGanghood deleted the fix/issue-57734-plugin-manifest-json-parse branch April 1, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin install fails: @vectorize-io/hindsight-openclaw config validation error (JSON syntax error at line 219)

1 participant