Skip to content

[select][combobox] Fix record items label lookup reading from Object.prototype - #5518

Merged
atomiks merged 2 commits into
mui:masterfrom
XionWCFM:fix/record-items-prototype-label
Aug 17, 2026
Merged

[select][combobox] Fix record items label lookup reading from Object.prototype#5518
atomiks merged 2 commits into
mui:masterfrom
XionWCFM:fix/record-items-prototype-label

Conversation

@XionWCFM

@XionWCFM XionWCFM commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #5517

Summary

When items is provided as a plain record map, resolveSelectedLabel read the label with (items as any)[value] ?? fallback(). The bracket lookup walks the prototype chain, so a selected value matching an Object.prototype member (constructor, toString, hasOwnProperty, __proto__, …) resolved to the inherited function instead of the fallback label. Since functions are never null/undefined, the ?? fallback never ran, and rendering the value via Select.Value / Combobox.Value crashed with "Functions are not valid as a React child."

The lookup now only reads own keys via Object.hasOwn, preserving the documented null placeholder key behavior (coerced to "null").

Why this is the established pattern in the codebase

This is the same prototype-chain trap that CheckboxGroup already guards against — checkbox values are consumer data, so a value like constructor must not read off Object.prototype:

  • checkbox-group/useCheckboxGroupParent.ts:17-18 uses a Map instead of an object for its value registry, with an explicit comment:

    A Map rather than an object: checkbox values are consumer data, and a value like constructor would otherwise read straight off Object.prototype.

  • checkbox-group/useCheckboxGroupParent.test.tsx:258 has a dedicated test, "does not read aria-controls ids off Object.prototype".

Form errors are keyed by field name (also consumer data), so the same collision is guarded with Object.hasOwn in form/Form.tsx:150, field/root/FieldRoot.tsx:94, and field/error/FieldError.tsx:41. This change brings the remaining record lookup in resolveSelectedLabel in line with those.

Test plan

  • Added regression tests in resolveValueLabel.test.ts covering:
    • prototype-member values falling back to the stringified label
    • an own record key that happens to match a prototype member still resolving
    • the null placeholder key in a record still resolving
  • pnpm test:jsdom resolveValueLabel --no-watch, SelectValue, ComboboxValue — all pass
  • pnpm eslint, pnpm typescript, pnpm prettier — clean

@pkg-pr-new

pkg-pr-new Bot commented Aug 16, 2026

Copy link
Copy Markdown

commit: 344d3bc

@code-infra-dashboard

code-infra-dashboard Bot commented Aug 16, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+27B(+0.01%) 🔺+6B(0.00%)

Details of bundle changes

Performance

Total duration: 1,180.54 ms -7.26 ms(-0.6%) | Renders: 76 (+0) | Paint: 1,866.52 ms +13.73 ms(+0.7%)

Test Duration Renders
Slider mount (300 instances) 128.66 ms 🔺+22.20 ms(+20.9%) 2 (+0)
Tooltip mount (300 contained roots) 55.93 ms 🔺+10.36 ms(+22.7%) 1 (+0)
Mixed surface mount (app-like density) 64.01 ms ▼-25.66 ms(-28.6%) 5 (+0)

12 tests within noise — details

Metric alarms

Test Metric Change
Slider mount (300 instances) bench:paint 🔺 +43.39 ms

Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Aug 16, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 344d3bc
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a828cfd3b7d7e0008713d43
😎 Deploy Preview https://deploy-preview-5518--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks atomiks added component: select Changes related to the select component. type: bug It doesn't behave as expected. labels Aug 17, 2026

@atomiks atomiks 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.

Thanks for the fix!

@atomiks
atomiks merged commit f2f2e19 into mui:master Aug 17, 2026
23 checks passed
@michaldudak michaldudak added the component: combobox Changes related to the combobox component. label Sep 1, 2026 — with ChatGPT Codex Connector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: combobox Changes related to the combobox component. component: select Changes related to the select component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[select][combobox] Record items: value matching an Object.prototype member resolves to a function instead of the fallback label

3 participants