fix: webhook notifications fail with "[object Object] is not valid JSON"#2641
fix: webhook notifications fail with "[object Object] is not valid JSON"#2641aldoeliacim wants to merge 3 commits intoseerr-team:developfrom
Conversation
The webhook `buildPayload` method correctly double-parses the stored
jsonPayload (`JSON.parse(JSON.parse(payloadString))`), expecting a
base64-encoded JSON string that wraps the actual JSON template.
However, the POST /webhook and POST /webhook/test routes only
single-encode the payload:
Buffer.from(req.body.options.jsonPayload).toString("base64")
This produces a base64 string that decodes directly to the JSON object
string. When buildPayload double-parses it, the first parse yields a
JS object, and the second parse calls toString() on that object,
producing "[object Object]" which is not valid JSON.
The fix wraps the payload with JSON.stringify() before base64-encoding,
matching the double-encoded format that buildPayload expects:
Buffer.from(JSON.stringify(req.body.options.jsonPayload)).toString("base64")
This is consistent with the default jsonPayload in settings/index.ts,
which is already stored in this double-encoded format.
Note: the default payload works because it was hardcoded as a
double-encoded base64 string. Only payloads saved via the API
(i.e., any user customization) trigger this bug.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughServer endpoints now JSON.stringify() the webhook JSON payload before base64-encoding and storing; the Settings UI stopped JSON.stringify-ing the payload before sending, so the server receives the raw value and performs the required double-encoding expected by the webhook agent. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR attempts to fix issue #2640 where webhook notifications fail with "[object Object] is not valid JSON". The fix adds JSON.stringify() wrapping before base64-encoding the jsonPayload in both the save and test webhook routes, aiming to produce the double-encoded format that buildPayload() in webhook.ts expects.
Changes:
- Wraps
req.body.options.jsonPayloadwithJSON.stringify()before base64-encoding in thePOST /webhooksave route - Applies the same
JSON.stringify()wrapping in thePOST /webhook/testtest route
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
gauthier-th
left a comment
There was a problem hiding this comment.
Please edit the PR description according to the PR template in https://github.com/seerr-team/seerr/blob/develop/.github/PULL_REQUEST_TEMPLATE.md
The UI's onSubmit and testSettings handlers were wrapping jsonPayload with JSON.stringify() before sending to the API. Combined with the server-side JSON.stringify added in the previous commit, this produced triple-encoding (Level 3) that buildPayload()'s double-parse couldn't handle. Remove the frontend stringify so the server is the single point of encoding normalization — both UI and direct API callers now go through the same path.
|
Updated the PR description to follow the template. Also addressed Copilot's review — the frontend was redundantly calling |
Description
Webhook notifications fail with
"[object Object]" is not valid JSONfor any webhook configuration saved via the API or UI.buildPayload()inwebhook.tsexpects a double-encoded payload (base64 → JSON string → JSON object):But the save routes (
POST /webhookandPOST /webhook/test) only single-encode the payload:Saved payloads decode to raw JSON (not a JSON-wrapped string), so the first
JSON.parseproduces an object, and the secondJSON.parsegets"[object Object]"instead of valid JSON. The default payload works because it was hardcoded as a pre-double-encoded base64 string.The fix wraps the payload with
JSON.stringify()before base64-encoding in both the save and test routes, producing the same double-encoded format thatbuildPayload()expects.How Has This Been Tested?
Screenshots / Logs (if applicable)
N/A
Checklist:
pnpm buildpnpm i18n:extractAI Disclosure
This PR was authored by @aldoeliacim with the help of Claude Code. The bug was discovered while debugging a production Jellyseerr v3.1.0 webhook integration.
Summary by CodeRabbit