Skip to content

Conversation

@Pragadesh-45
Copy link
Contributor

@Pragadesh-45 Pragadesh-45 commented Dec 29, 2025

Fixes: #6486
Related to: #1693

Description

The Bruno CLI was sending an unwanted Content-Type: application/x-www-form-urlencoded header for requests with no body. This fix ensures that requests with no body do not send a Content-Type header, matching the behavior of the Electron version.

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Summary by CodeRabbit

  • Bug Fixes
    • Made Content-Type handling more robust to avoid runtime errors when the header is missing or not a string; improves handling for JSON, form-encoded, and multipart requests.
    • Added support for a request body mode of "none" to prevent automatic injection of a Content-Type header when no body is intended, improving request signing compatibility.
    • No public API changes.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 29, 2025

Walkthrough

Type guards were added to ensure contentType is a string in interpolate-vars.js; getContentType returns '' for non-strings. prepare-request.js sets axiosRequest.headers['Content-Type'] = null when request.body.mode === 'none' and request.auth.mode !== 'awsv4' to prevent Axios from adding a default header.

Changes

Cohort / File(s) Summary
Body/Header Type Guards
packages/bruno-cli/src/runner/interpolate-vars.js
Add typeof contentType === 'string' guards; getContentType returns '' for non-string values to avoid runtime errors when using string methods (e.g., .includes) across JSON, form-urlencoded, and multipart handling.
No-Body Content-Type Handling
packages/bruno-cli/src/runner/prepare-request.js
When request.body.mode === 'none' and request.auth.mode !== 'awsv4', set axiosRequest.headers['Content-Type'] = null (inserted after GraphQL handling and before script handling) so Axios does not auto-add a Content-Type header.

Sequence Diagram(s)

(omitted — changes are localized and do not introduce multi-component sequential flows requiring a diagram)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

size/XS

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

No body, no default hum,
Guards in place, no methods numb,
Content-Type set gently null,
Axios quiet, headers lull,
Small patch — the request stays calm.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: improving Content-Type handling when request body is none, directly addressing issue #6486.
Linked Issues check ✅ Passed The changes directly address issue #6486 by preventing unwanted Content-Type headers when body mode is 'none', ensuring CLI behavior matches the Electron client.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing Content-Type header handling for 'none' body mode; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e91d30 and ceada14.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/interpolate-vars.js
  • packages/bruno-cli/src/runner/prepare-request.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-cli/src/runner/interpolate-vars.js
  • packages/bruno-cli/src/runner/prepare-request.js
🧠 Learnings (2)
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-cli/src/runner/interpolate-vars.js
  • packages/bruno-cli/src/runner/prepare-request.js
📚 Learning: 2025-12-02T07:24:50.311Z
Learnt from: bijin-bruno
Repo: usebruno/bruno PR: 6263
File: packages/bruno-requests/src/auth/oauth2-helper.ts:249-249
Timestamp: 2025-12-02T07:24:50.311Z
Learning: In OAuth2 Basic Auth headers for Bruno, clientSecret is optional and can be omitted. When constructing the Authorization header in `packages/bruno-requests/src/auth/oauth2-helper.ts`, use `clientSecret || ''` instead of `clientSecret!` to properly handle cases where only clientId is provided, per community requests.

Applied to files:

  • packages/bruno-cli/src/runner/prepare-request.js
🧬 Code graph analysis (1)
packages/bruno-cli/src/runner/interpolate-vars.js (5)
packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js (1)
  • contentType (1498-1498)
packages/bruno-app/src/utils/common/index.js (1)
  • contentType (97-97)
packages/bruno-tests/src/index.js (1)
  • contentType (30-30)
packages/bruno-electron/src/ipc/network/interpolate-vars.js (2)
  • contentType (6-6)
  • contentType (76-76)
packages/bruno-app/src/utils/codegenerator/har.js (2)
  • contentType (39-39)
  • contentType (69-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
🔇 Additional comments (2)
packages/bruno-cli/src/runner/interpolate-vars.js (1)

13-14: LGTM! Type guard prevents downstream string operation errors.

The type guard correctly ensures getContentType always returns a string, preventing issues when the content-type header is null, undefined, or false (as set in prepare-request.js for mode 'none'). This safeguards downstream operations like .includes() at line 69.

packages/bruno-cli/src/runner/prepare-request.js (1)

379-388: LGTM! Properly handles 'none' body mode while respecting AWS SigV4 requirements.

The implementation correctly:

  • Sets Content-Type to null for body mode 'none' to prevent axios from adding a default header
  • Excludes AWS SigV4 auth (which requires Content-Type for canonical request signature calculation)
  • Guards against undefined request.auth with (!request.auth || request.auth.mode !== 'awsv4')
  • Respects explicitly defined Content-Type headers via the contentTypeDefined check
  • Includes clear comments explaining both the fix (When specifying "No Body" a Content-Type header is still sent #1693) and the AWS SigV4 exception

The use of lowercase 'content-type' at line 386 is consistent with other header assignments in this file.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/bruno-cli/src/runner/prepare-request.js (1)

383-383: Consider case consistency for Content-Type header.

Line 383 uses 'Content-Type' (capitalized), while earlier in the file (lines 292, 303, 310, 317, 324, 332, 356, 363, 374) the code uses 'content-type' (lowercase). While Axios may normalize header names, maintaining consistent casing improves code readability.

🔎 Suggested change
-      axiosRequest.headers['Content-Type'] = null;
+      axiosRequest.headers['content-type'] = null;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 018f392 and 48e208f.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/interpolate-vars.js
  • packages/bruno-cli/src/runner/prepare-request.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-cli/src/runner/interpolate-vars.js
🧠 Learnings (2)
📚 Learning: 2025-12-02T07:24:50.311Z
Learnt from: bijin-bruno
Repo: usebruno/bruno PR: 6263
File: packages/bruno-requests/src/auth/oauth2-helper.ts:249-249
Timestamp: 2025-12-02T07:24:50.311Z
Learning: In OAuth2 Basic Auth headers for Bruno, clientSecret is optional and can be omitted. When constructing the Authorization header in `packages/bruno-requests/src/auth/oauth2-helper.ts`, use `clientSecret || ''` instead of `clientSecret!` to properly handle cases where only clientId is provided, per community requests.

Applied to files:

  • packages/bruno-cli/src/runner/prepare-request.js
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-cli/src/runner/interpolate-vars.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - Windows
🔇 Additional comments (4)
packages/bruno-cli/src/runner/interpolate-vars.js (4)

13-14: LGTM! Proper type guard for contentType.

The guard prevents runtime errors when contentType is null or other non-string values, which can now happen with the changes in prepare-request.js. The empty string fallback is appropriate.


69-69: LGTM! Type guard prevents runtime error.

The guard ensures .includes() is only called on string values. This prevents TypeErrors when contentType is null.


83-83: LGTM! Consistent type guard.

Type guard ensures string comparison is safe and aligns with the pattern used throughout the file.


90-90: LGTM! Complete type guard coverage.

This completes the type guard pattern for all contentType checks in the interpolation logic. All branches now safely handle non-string contentType values.

@Pragadesh-45 Pragadesh-45 force-pushed the fix/6486 branch 3 times, most recently from a42dab3 to 8e91d30 Compare December 29, 2025 13:55
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/bruno-cli/src/runner/interpolate-vars.js (1)

69-69: Type guards are technically redundant but acceptable.

Since getContentType now always returns a string (line 14), these typeof checks are redundant. However, they make the code more explicit and provide defense-in-depth if getContentType is modified later. The consistency across all three branches is also a plus.

Also applies to: 83-83, 90-90

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a42dab3 and 8e91d30.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/interpolate-vars.js
  • packages/bruno-cli/src/runner/prepare-request.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-cli/src/runner/prepare-request.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-cli/src/runner/interpolate-vars.js
🧠 Learnings (1)
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-cli/src/runner/interpolate-vars.js
🧬 Code graph analysis (1)
packages/bruno-cli/src/runner/interpolate-vars.js (4)
packages/bruno-tests/src/index.js (1)
  • contentType (30-30)
packages/bruno-electron/src/ipc/network/interpolate-vars.js (2)
  • contentType (6-6)
  • contentType (76-76)
packages/bruno-app/src/utils/codegenerator/har.js (2)
  • contentType (39-39)
  • contentType (69-69)
packages/bruno-app/src/utils/collections/index.js (2)
  • request (588-588)
  • request (1065-1065)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: CLI Tests
  • GitHub Check: Unit Tests
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
🔇 Additional comments (1)
packages/bruno-cli/src/runner/interpolate-vars.js (1)

13-14: LGTM! Defensive type guard improves robustness.

Returning empty string for non-string content-type values prevents potential runtime errors and ensures consistent behavior when headers contain unexpected values.

@bijin-bruno bijin-bruno merged commit 1174f22 into usebruno:main Jan 6, 2026
8 checks passed
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.

When specifying "No Body" a Content-Type header is still sent

2 participants