Summary
Comments in a body:json block are not stripped by the VS Code extension, and the request ends up being sent as a JSON string instead of a JSON object. The same collection works fine in the desktop app, which strips comments with decomment.
The whole body arrives at the server wrapped in double quotes, as a single JSON string, instead of an object. On a strict API this surfaces as a confusing 400 — our Django/DRF backend answers Invalid data. Expected a dictionary, but got str.
Details
Extension version: 5.0.2 (v5.0.2-2026.08.20)
VSCode version: 1.134.0
OS: Windows 11
Also affects the desktop app? No — Bruno 4.1.0 desktop sends the same request correctly.
Root cause
src/extension/ipc/network/prepare-request.ts builds the body like this:
case 'json':
headers['content-type'] = headers['content-type'] || 'application/json';
try {
return body.json ? JSON.parse(body.json) : undefined;
} catch {
return body.json;
}
Any // comment makes JSON.parse throw, so the catch returns the raw commented text. That string is handed to axios with content-type: application/json, and axios' stringifySafely cannot parse it either, so it falls back to JSON.stringify(rawString) — the body goes out double-encoded, as a quoted string.
Correction to an earlier version of this issue: decomment is not a dependency of this repo. src/extension/utils/script-runner.ts declares a local decomment that currently returns the script untouched, so nothing strips comments anywhere in the extension. The desktop app and the CLI do apply the real package to the body:
packages/bruno-electron/src/ipc/network/prepare-request.js -> axiosRequest.data = decomment(request?.body?.json)
packages/bruno-cli/src/runner/prepare-request.js -> same
So a collection authored in the desktop app (where JSON body comments are supported since usebruno/bruno#396) silently breaks when the same .bru files are run from VS Code. In our shared collection, 80 of 127 requests with a JSON body are affected.
Steps to reproduce
- Create a request with a commented JSON body:
meta {
name: comment-repro
type: http
seq: 1
}
post {
url: https://echo.usebruno.com
body: json
auth: none
}
body:json {
{
"a": 1 // this comment breaks it
}
}
- Send it from the VS Code extension and look at the request body in the Timeline.
- Remove the comment and send it again.
Actual: with the comment, the payload is the body text itself, quoted and escaped as a single JSON string. Without the comment, the object is sent correctly.
Expected: the comment is stripped and the object is sent, the way the desktop app does it.
Suggested fix
Strip the comments in the json case of prepare-request.ts, and make the fallback return the
comment-free text rather than the raw body:
case 'json': {
headers['content-type'] = headers['content-type'] || 'application/json';
if (!body.json) return undefined;
const json = stripJsonComments(body.json);
try {
return JSON.parse(json);
} catch {
// Unquoted variables are only resolved later, by interpolation.
return json;
}
}
The fallback matters: a body that mixes comments with unquoted variables ("quantity": {{qty}})
is still not valid JSON after stripping, so it takes that path, and returning the raw text keeps
the // in the string that reaches interpolate-vars — those requests stay double-encoded.
PR: #138. Since decomment is not a dependency here, it adds a small dependency-free helper
rather than pulling the package in; swapping it for decomment to match bruno-electron byte for
byte is a one-line change if that is preferred.
Related upstream: usebruno/bruno#396 (comments in JSON body, implemented for desktop/CLI) and usebruno/bruno#8055 (invalid JSON bodies being quoted).
Summary
Comments in a
body:jsonblock are not stripped by the VS Code extension, and the request ends up being sent as a JSON string instead of a JSON object. The same collection works fine in the desktop app, which strips comments withdecomment.The whole body arrives at the server wrapped in double quotes, as a single JSON string, instead of an object. On a strict API this surfaces as a confusing 400 — our Django/DRF backend answers
Invalid data. Expected a dictionary, but got str.Details
Extension version: 5.0.2 (
v5.0.2-2026.08.20)VSCode version: 1.134.0
OS: Windows 11
Also affects the desktop app? No — Bruno 4.1.0 desktop sends the same request correctly.
Root cause
src/extension/ipc/network/prepare-request.tsbuilds the body like this:Any
//comment makesJSON.parsethrow, so thecatchreturns the raw commented text. That string is handed to axios withcontent-type: application/json, and axios'stringifySafelycannot parse it either, so it falls back toJSON.stringify(rawString)— the body goes out double-encoded, as a quoted string.Correction to an earlier version of this issue:
decommentis not a dependency of this repo.src/extension/utils/script-runner.tsdeclares a localdecommentthat currently returns the script untouched, so nothing strips comments anywhere in the extension. The desktop app and the CLI do apply the real package to the body:packages/bruno-electron/src/ipc/network/prepare-request.js->axiosRequest.data = decomment(request?.body?.json)packages/bruno-cli/src/runner/prepare-request.js-> sameSo a collection authored in the desktop app (where JSON body comments are supported since usebruno/bruno#396) silently breaks when the same
.brufiles are run from VS Code. In our shared collection, 80 of 127 requests with a JSON body are affected.Steps to reproduce
Actual: with the comment, the payload is the body text itself, quoted and escaped as a single JSON string. Without the comment, the object is sent correctly.
Expected: the comment is stripped and the object is sent, the way the desktop app does it.
Suggested fix
Strip the comments in the
jsoncase ofprepare-request.ts, and make the fallback return thecomment-free text rather than the raw body:
The fallback matters: a body that mixes comments with unquoted variables (
"quantity": {{qty}})is still not valid JSON after stripping, so it takes that path, and returning the raw text keeps
the
//in the string that reachesinterpolate-vars— those requests stay double-encoded.PR: #138. Since
decommentis not a dependency here, it adds a small dependency-free helperrather than pulling the package in; swapping it for
decommentto matchbruno-electronbyte forbyte is a one-line change if that is preferred.
Related upstream: usebruno/bruno#396 (comments in JSON body, implemented for desktop/CLI) and usebruno/bruno#8055 (invalid JSON bodies being quoted).