Skip to content

jsc: use 'property' wording in get_optional_slice type error - #32355

Merged
alii merged 3 commits into
mainfrom
farm/6a256462/fix-get-optional-slice-error-message
Jun 15, 2026
Merged

alii merged 3 commits into
mainfrom
farm/6a256462/fix-get-optional-slice-error-message

Conversation

@robobun

@robobun robobun commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Repro

try { new Bun.Terminal({ name: 12345 }) } catch (e) { console.log(e.message) }

Before:

The "name" argument must be of type string. Received type number (12345)

After (matches Zig 1.3.14):

The "name" property must be of type string, got number

Cause

JSValue::get_optional_slice in src/jsc/JSValue.rs reads a property from an options object but called throw_invalid_argument_type_value, which produces the "argument ... Received" format. The Zig reference (getOptional(... ZigString.Slice) in src/jsc/JSValue.zig) routes through jsc.Node.validators.throwErrInvalidArgType, which produces the "property ... got" format.

This affects every caller of get_optional_slice: Bun.Terminal (name), Bun.build (target, outdir, banner, footer, root, publicPath, naming.*, jsx.*), Bun.serve static routes (index, dir), and Bun.CSRF (sessionId, secret).

Fix

Route through throw_invalid_property_type, which already exists and is what get_boolean_strict uses for the identical situation. Also fixed the local get_optional_slice shim in src/runtime/api/csrf_jsc.rs which had the same bug.

Verification

Added a test to test/js/bun/terminal/terminal.test.ts asserting the exact {code, name, message} shape.

$ bun bd test test/js/bun/terminal/terminal.test.ts
 88 pass
 1 todo
 0 fail

$ bun bd test test/js/bun/util/csrf.test.ts
 24 pass
 0 fail

get_optional_slice reads a property from an options object, so the
ERR_INVALID_ARG_TYPE message should say 'property' (matching the Zig
reference getOptional ZigString.Slice path via throwErrInvalidArgType)
rather than 'argument'. Routes through throw_invalid_property_type,
the same helper get_boolean_strict already uses.

Also fixes the identical local shim in csrf_jsc.rs.
alii
alii previously approved these changes Jun 15, 2026
@alii
alii enabled auto-merge (squash) June 15, 2026 19:47
@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2957d249-c85d-42ff-9ba3-579afe4847ee

📥 Commits

Reviewing files that changed from the base of the PR and between fcd3ff0 and 506f58f.

📒 Files selected for processing (1)
  • src/runtime/api/csrf_jsc.rs

Walkthrough

JSValue::get_optional_slice now throws throw_invalid_property_type for non-string properties. csrf_jsc removes its local get_optional_slice helper and updates call sites to use the updated JSValue method directly. A terminal constructor test validates the resulting error message.

Changes

Non-string property error helper alignment

Layer / File(s) Summary
Error helper swap in JSValue and csrf_jsc
src/jsc/JSValue.rs, src/runtime/api/csrf_jsc.rs
JSValue::get_optional_slice switches from throw_invalid_argument_type_value to throw_invalid_property_type for type mismatches. csrf_jsc removes its local get_optional_slice helper and updates three call sites—in csrf__generate for sessionId and in csrf__verify for secret and sessionId—to call JSValue::get_optional_slice directly.
Terminal constructor test for invalid name type
test/js/bun/terminal/terminal.test.ts
Adds a test asserting that passing a non-string name option to Bun.Terminal throws a TypeError with code ERR_INVALID_ARG_TYPE and a message indicating the "name" property must be of type string, got number.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: updating error message wording in get_optional_slice from 'argument' to 'property' format.
Description check ✅ Passed The description comprehensively covers the PR objectives with clear sections on issue, cause, fix, and verification, exceeding the template requirements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — straightforward error-message wording fix with a test; the two inline nits are optional cleanups, not blockers.

Extended reasoning...

Overview

This PR swaps a single error-throwing call in JSValue::get_optional_slice (and its duplicate local shim in csrf_jsc.rs) from throw_invalid_argument_type_value to throw_invalid_property_type, so that type errors on options-object properties say "property ... got" instead of "argument ... Received" — matching the Zig reference implementation. A regression test is added in terminal.test.ts asserting the exact {code, name, message} shape. Net diff: 2 lines changed in source, 4 lines deleted, 14 lines of test added.

Security risks

None. This only affects the text of a TypeError thrown on the validation-failure path. The error code (ERR_INVALID_ARG_TYPE) and error class are unchanged, no new inputs are accepted, and the happy path is untouched.

Level of scrutiny

Low. The change is cosmetic (error-message wording), type-checks against the existing throw_invalid_property_type(name: impl AsRef<[u8]>, ...) signature, and follows the established pattern already used by get_boolean_strict a few lines below. Both relevant test suites (terminal.test.ts, csrf.test.ts) pass per the PR description.

Other factors

The bug-hunter surfaced two nits: (1) sibling algorithm/expiresIn/maxAge checks in the same CSRF file still use "argument" wording, and (2) the local get_optional_slice shim is now byte-identical to the public method and could be deleted. Both are valid cleanup suggestions but neither is a correctness issue or a regression — they're pre-existing inconsistencies that this PR partially improves. Fine to land as-is and address in a follow-up.

Comment thread src/runtime/api/csrf_jsc.rs Outdated
Comment thread src/runtime/api/csrf_jsc.rs Outdated
The shim became identical to JSValue::get_optional_slice after the
previous commit; delete it and call the method directly.
@robobun

robobun commented Jun 15, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 4:48 PM PT - Jun 15th, 2026

✅ @robobun, your commit 1c058d4b0156df58e70d6f161c02e72f6701c307 passed in Build #62664! 🎉


🧪   To try this PR locally:

bunx bun-pr 32355

That installs a local version of the PR into your bun-32355 executable, so you can run:

bun-32355 --bun

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — thanks for deleting the shim; the remaining algorithm/expiresIn wording nit is cosmetic and fine for a follow-up.

Extended reasoning...

Overview

One-line change in src/jsc/JSValue.rs swapping throw_invalid_argument_type_value → throw_invalid_property_type inside get_optional_slice, so type errors for option-bag properties read "property … got" (matching the Zig reference and get_boolean_strict) instead of "argument … Received". src/runtime/api/csrf_jsc.rs deletes the now-redundant local get_optional_slice shim and points its 3 callers at the JSValue method (addressed my earlier nit in 506f58f). A new test in terminal.test.ts pins the exact {code, name, message} shape.

Security risks

None. This only changes the text of a TypeError thrown on the invalid-input path; the error code (ERR_INVALID_ARG_TYPE) and class are unchanged. No auth/crypto/permission logic is touched — csrf_jsc.rs edits are a pure refactor of which helper is called, with the token generate/verify logic untouched.

Level of scrutiny

Low. The new helper already exists (JSGlobalObject::throw_invalid_property_type, takes impl AsRef<[u8]> + &str + JSValue), so the signature swap is type-checked by rustc. The shim deletion is behaviorally identical (I verified line-by-line equivalence in my prior review), and get_optional_slice is already called as a method elsewhere in bun_runtime. None of the touched files are under CODEOWNERS.

Other factors

Author ran both affected suites (terminal.test.ts 88 pass, csrf.test.ts 24 pass). Bug-hunting found nothing this round. My other prior nit — that algorithm / get_optional_int_u64 in csrf_jsc.rs still use the "argument" wording — was explicitly cosmetic and non-blocking; leaving it out of scope here is a reasonable call.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — thanks for deleting the shim.

Extended reasoning...

Overview

One-line swap in JSValue::get_optional_slice (src/jsc/JSValue.rs:1213) from throw_invalid_argument_type_value to throw_invalid_property_type, so type errors for option-bag properties say "property … got" instead of "argument … Received", matching the Zig reference. The follow-up commit (506f58f) deletes the now-redundant local get_optional_slice shim in src/runtime/api/csrf_jsc.rs and rewrites three call sites to use the JSValue method directly. A new test in terminal.test.ts pins the exact {code, name, message} shape.

Security risks

None. This only changes error-message text; the error code (ERR_INVALID_ARG_TYPE) and class (TypeError) are unchanged. No new inputs, no new control flow, no auth/crypto logic touched (the CSRF file edit is a pure call-site rename to an identical helper).

Level of scrutiny

Low. The JSValue.rs change is a one-token helper swap whose target (throw_invalid_property_type) already exists, takes impl AsRef<[u8]> for the name (so the &[u8] property binding still fits), and is already used by the sibling get_boolean_strict. The csrf_jsc.rs change is mechanical dead-code removal I suggested in the prior review round; the three call sites now invoke a method whose body is byte-identical to the deleted shim.

Other factors

Both of my earlier nits are resolved: the shim deletion was applied, and the author gave a reasonable reference-matching rationale for leaving algorithm / get_optional_int_u64 as-is (they track different Zig paths). The bug-hunting pass found nothing on the latest revision, CodeRabbit had no actionable comments, and the PR carries passing test runs for both affected suites.

@robobun

robobun commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

CI status: the diff is green.

  • Build #62664: 73 jobs passed. The only red is darwin-26-aarch64-test-bun which Expired waiting for an agent (no macOS 26 runner picked it up). No test failures on any lane that actually ran; terminal.test.ts and csrf.test.ts both pass on every platform.
  • Earlier build #62644 showed a terminal.test.ts failure on darwin-14-aarch64, but the failing test (NaN clamps to tcflag_t max, same as Infinity) does not exist in this commit or on main; it comes from Fix Bun.Terminal termios flag NaN clamping #32354. That tart VM had a stale checkout of the other PR's test file while running this PR's binary. The retrigger cleared it (darwin-14-aarch64 passed on #62664).
  • Remaining flaky-tagged retries (spawn.test.ts Windows timeout, streams-leak.test.ts aarch64, serve-body-leak.test.ts asan threshold, hot.test.ts Windows ENOENT, bun-create.test.ts NPMIsDown, package.json GitHub 5xx) are all unrelated infra/network and passed on retry or are known flakes.

Ready to merge when a maintainer is satisfied with the CI state.

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.

2 participants