Skip to content

fix(discord): guard JSON.parse against malformed API response bodies#97889

Merged
vincentkoc merged 7 commits into
openclaw:mainfrom
lsr911:fix/discord-json-parse-guard
Jul 2, 2026
Merged

fix(discord): guard JSON.parse against malformed API response bodies#97889
vincentkoc merged 7 commits into
openclaw:mainfrom
lsr911:fix/discord-json-parse-guard

Conversation

@lsr911

@lsr911 lsr911 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

extensions/discord/src/api.ts:198 calls JSON.parse(text) on the Discord API response body without try/catch. Malformed JSON → unhandled SyntaxError → process crash.

Changes

  • extensions/discord/src/api.ts: wrap JSON.parse(text) in try/catch → DiscordApiError("malformed JSON", 0)
  • extensions/discord/src/api.test.ts: test verifying malformed JSON → DiscordApiError
  • test/_proof_discord_json_guard.mts: v3 — calls requestDiscord with custom fetcher returning malformed JSON, exercises actual changed code path

Label: bugfix | merge-risk: 🟢 minimal | AI-assisted

Evidence

Real HTTP proof — calls requestDiscord (L2)

$ node --import tsx test/_proof_discord_json_guard.mts

PASS  malformed JSON: throws DiscordApiError :: type=DiscordApiError
PASS  malformed JSON: message describes malformed JSON :: msg="Discord API /users/@me returned malformed JSON"
PASS  malformed JSON: status=0 (not retryable) :: status=0
PASS  rate-limit: still throws DiscordApiError :: type=DiscordApiError
PASS  rate-limit: status preserved :: status=429
PASS  valid JSON: parsed correctly :: result={"id":"42","name":"test"}

[proof] 6 PASS, 0 FAIL

Unit test

pnpm exec vitest run extensions/discord/src/api.test.ts
 ✓ throws DiscordApiError on malformed JSON success response body
 Test Files  1 passed (1)

Fix history

  • v1: catch (cause) → lint error
  • v2: → catch + standalone proof (manually simulated)
  • v3: proof calls requestDiscord with custom fetcher returning malformed JSON, exercises the actual changed try/catch path

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: XS labels Jun 29, 2026
@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 8:28 PM ET / 00:28 UTC.

Summary
The branch wraps Discord requestDiscord successful-response JSON.parse failures in DiscordApiError and adds a colocated malformed-JSON regression test.

PR surface: Source +7, Tests +18. Total +25 across 2 files.

Reproducibility: yes. A custom fetcher returning malformed HTTP 200 JSON through fetchDiscord/requestDiscord directly exercises current main's raw parse path; I did not run it because this review is read-only, but the source path is direct and the PR body includes terminal proof.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: serialized state: extensions/discord/src/api.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: canonical
Canonical: #97889
Summary: This PR is the canonical candidate for malformed successful JSON in Discord requestDiscord; the Matrix sibling is merged and the Discord webhook OOM PR is adjacent but distinct.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Next step before merge

  • No automated repair remains; a maintainer needs to clear the explicit human-review/automerge pause or decide not to land this PR.

Security
Cleared: No concrete security or supply-chain regression was found; the diff hardens Discord response parsing and does not change dependencies, workflows, permissions, package metadata, or secret handling.

Review details

Best possible solution:

Land the narrow requestDiscord parse guard and regression test once a maintainer clears the human-review/automerge gate.

Do we have a high-confidence way to reproduce the issue?

Yes. A custom fetcher returning malformed HTTP 200 JSON through fetchDiscord/requestDiscord directly exercises current main's raw parse path; I did not run it because this review is read-only, but the source path is direct and the PR body includes terminal proof.

Is this the best way to solve the issue?

Yes. Catching the parse failure inside requestDiscord is the narrow owner-boundary fix because fetchDiscord callers share that helper and the retry policy already limits retries to Discord 429 errors.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3558391a75fd.

Label changes

Label justifications:

  • P2: This is a normal-priority Discord robustness bugfix with limited blast radius in one shared API helper and its colocated regression test.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body includes after-fix terminal output exercising malformed, rate-limited, and valid requestDiscord paths, and the final head keeps the runtime guard plus regression test.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output exercising malformed, rate-limited, and valid requestDiscord paths, and the final head keeps the runtime guard plus regression test.
Evidence reviewed

PR surface:

Source +7, Tests +18. Total +25 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 8 1 +7
Tests 1 18 0 +18
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 26 1 +25

What I checked:

Likely related people:

  • Eva: git blame for the current requestDiscord helper and raw parse line points to commit 48974b5765d36b5229dd22dba27952b6a10dcb25. (role: current implementation author; confidence: medium; commits: 48974b5765d3; files: extensions/discord/src/api.ts, extensions/discord/src/api.test.ts)
  • Ayaan Zaidi: The same current-helper blame commit was committed by Ayaan Zaidi, making them a routing candidate for the current shape of this file. (role: committer of current implementation; confidence: medium; commits: 48974b5765d3; files: extensions/discord/src/api.ts)
  • steipete: Path history shows Peter Steinberger authored the retry runtime SDK seam and earlier Discord API retry/error work that this helper relies on. (role: adjacent retry/API contributor; confidence: high; commits: c222a44e6f4e, f70ac0c7c239, 80e6c070bfc2; files: extensions/discord/src/api.ts, src/plugin-sdk/retry-runtime.ts, src/infra/retry.ts)
  • scoootscooob: Path history shows this contributor moved the Discord implementation into extensions/, defining the current plugin owner boundary for this code. (role: extension migration contributor; confidence: medium; commits: 5682ec37fada; files: extensions/discord/src/api.ts, src/discord/api.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 29, 2026
@lsr911
lsr911 force-pushed the fix/discord-json-parse-guard branch from 29e4b74 to 73da0d9 Compare June 29, 2026 18:43
@lsr911
lsr911 force-pushed the fix/discord-json-parse-guard branch from 73da0d9 to 853e64a Compare June 30, 2026 01:35
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 30, 2026
@Takhoffman

Copy link
Copy Markdown
Contributor

@clawsweeper automerge

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper automerge is enabled.

  • Head: 3573b455d2fd
  • Label: clawsweeper:automerge
  • Action: exact-head review queued (workflow sweep.yml, event repository_dispatch).
  • Flow: review this head, repair/rebase only if needed, then re-review the exact repaired head before merge.

Draft PRs stay fix-only until GitHub marks them ready for review. Pause with /clawsweeper stop.

Automerge progress:

  • 2026-07-01 23:43:39 UTC review queued c8d650d8a10b (queued)
  • 2026-07-02 00:07:37 UTC review requested repair 8911d2507393 (structured ClawSweeper needs-human verdict with repairable P-severity findings...)
  • 2026-07-02 00:01:04 UTC review queued 8911d2507393 (queued)
  • 2026-07-02 00:11:22 UTC review queued 3573b455d2fd (after repair)
  • 2026-07-02 00:17:30 UTC review queued 3573b455d2fd (queued)

@clawsweeper clawsweeper Bot added the clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge label Jul 1, 2026
@clawsweeper
clawsweeper Bot force-pushed the fix/discord-json-parse-guard branch from 853e64a to 9dadf44 Compare July 1, 2026 12:01
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 1, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. labels Jul 1, 2026
lsr911 and others added 7 commits July 2, 2026 00:05
Wrap JSON.parse(text) in requestDiscord with try/catch to prevent a malformed Discord API response body from throwing an unhandled SyntaxError and crashing the process. On parse failure, throw a DiscordApiError with a descriptive message so the caller can handle it gracefully.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: lsr911 <[email protected]>
@clawsweeper
clawsweeper Bot force-pushed the fix/discord-json-parse-guard branch from 8911d25 to 3573b45 Compare July 2, 2026 00:11
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. clawsweeper:human-review Needs maintainer review before ClawSweeper can continue and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 2, 2026
@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper is pausing this repair loop for human review.

Source: clawsweeper[bot]
Reason: - No automated repair remains; a maintainer needs to clear the explicit human-review/automerge pause or decide not to land this PR.; Cleared: No concrete security or supply-chain regression was found; the diff hardens Discord response parsing and does not change dependencies, workflows, permissions, package metadata, or secret handling. (sha=3573b455d2fdaec2891d3660abc7e37fcccbef88)

Why human review is needed:
This item has security-sensitive risk. ClawSweeper is pausing instead of making an autonomous change that could affect trust, credentials, permissions, or exposure.

What the maintainer can do as a next step:
If the maintainer accepts the current risk and wants ClawSweeper to continue merge gates, comment @clawsweeper approve. If the security-sensitive detail still needs changes, describe the safe path or push the fix, then comment @clawsweeper automerge. If the risk should not be automated, keep the PR paused for manual review or comment @clawsweeper stop.

I added clawsweeper:human-review and left the final call with a maintainer.

@vincentkoc vincentkoc self-assigned this Jul 2, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Maintainer review complete on exact head 3573b455d2fdaec2891d3660abc7e37fcccbef88.

Land-ready proof:

  • node scripts/run-vitest.mjs extensions/discord/src/api.test.ts - 17/17 passed.
  • Direct requestDiscord malformed-JSON probe with retry.attempts=3 - returned DiscordApiError with status 0, exact path diagnostic, and one fetch call.
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --stream-engine-output - clean, no findings, correctness confidence 0.98.
  • git diff --check origin/main...HEAD - passed.
  • OPENCLAW_TESTBOX=1 scripts/pr prepare-run 97889 - exact-head hosted CI/Testbox gates passed; 57 relevant checks complete with no failures or pending checks.

The ordinary local prepare path was intentionally stopped when pnpm asked to remove and reinstall all workspace module directories from the symlinked worktree. That was a dependency-layout prompt, not a patch failure; no shared modules were modified.

The final merge-base diff remains the narrow two-file Discord response guard. Valid JSON, blank bodies, response-size limits, and HTTP 429 retry behavior remain unchanged; malformed successful JSON now uses the owned non-retryable Discord error type.

@vincentkoc
vincentkoc merged commit 050e1f3 into openclaw:main Jul 2, 2026
113 of 120 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

vincentkoc added a commit that referenced this pull request Jul 2, 2026
* origin/main:
  test(gateway): isolate live release agent state
  test(plugins): repair prerelease validation fixtures
  fix(discord): guard JSON.parse against malformed API response bodies (#97889)
  fix(codex): preserve app approvals in side forks (#98812)
  fix(agents): don't inject A2A turns into isolated-cron sessions_send (#92257) (#92283)
  fix(browser): guard setDeep against empty keys array (#98138)
  docs(telegram): move maintainer decisions into scoped AGENTS.md
  fix(ios): generate light app store screenshots only
  fix(gateway): distinguish reachable gateway from failed status probe (#98183)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 2, 2026
…penclaw#97889)

* fix(discord): guard JSON.parse against malformed API response bodies

Wrap JSON.parse(text) in requestDiscord with try/catch to prevent a malformed Discord API response body from throwing an unhandled SyntaxError and crashing the process. On parse failure, throw a DiscordApiError with a descriptive message so the caller can handle it gracefully.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: lsr911 <[email protected]>

* fix(clawsweeper): address review for automerge-openclaw-openclaw-97889 (validation-1)

* chore: trigger CI re-run for flaky checks-node-compact-small-whole-2

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky runtime-inventory-drift-check

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky checks-node-compact-large-whole-1

Signed-off-by: lsr911 <[email protected]>

* fix(discord): guard JSON.parse against malformed API response bodies

* fix(discord): guard JSON.parse against malformed API response bodies

---------

Signed-off-by: lsr911 <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
…penclaw#97889)

* fix(discord): guard JSON.parse against malformed API response bodies

Wrap JSON.parse(text) in requestDiscord with try/catch to prevent a malformed Discord API response body from throwing an unhandled SyntaxError and crashing the process. On parse failure, throw a DiscordApiError with a descriptive message so the caller can handle it gracefully.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: lsr911 <[email protected]>

* fix(clawsweeper): address review for automerge-openclaw-openclaw-97889 (validation-1)

* chore: trigger CI re-run for flaky checks-node-compact-small-whole-2

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky runtime-inventory-drift-check

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky checks-node-compact-large-whole-1

Signed-off-by: lsr911 <[email protected]>

* fix(discord): guard JSON.parse against malformed API response bodies

* fix(discord): guard JSON.parse against malformed API response bodies

---------

Signed-off-by: lsr911 <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
sheyanmin pushed a commit to sheyanmin/openclaw that referenced this pull request Jul 8, 2026
…penclaw#97889)

* fix(discord): guard JSON.parse against malformed API response bodies

Wrap JSON.parse(text) in requestDiscord with try/catch to prevent a malformed Discord API response body from throwing an unhandled SyntaxError and crashing the process. On parse failure, throw a DiscordApiError with a descriptive message so the caller can handle it gracefully.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: lsr911 <[email protected]>

* fix(clawsweeper): address review for automerge-openclaw-openclaw-97889 (validation-1)

* chore: trigger CI re-run for flaky checks-node-compact-small-whole-2

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky runtime-inventory-drift-check

Signed-off-by: lsr911 <[email protected]>

* chore: trigger CI re-run for flaky checks-node-compact-large-whole-1

Signed-off-by: lsr911 <[email protected]>

* fix(discord): guard JSON.parse against malformed API response bodies

* fix(discord): guard JSON.parse against malformed API response bodies

---------

Signed-off-by: lsr911 <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge clawsweeper:human-review Needs maintainer review before ClawSweeper can continue P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: XS status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants