payloadcms / payloadcms/payload
Admin dashboard: breadcrumb select's combobox input has no accessible name (axe label, critical)
@JessRynkar is already working on this.
Since Sep 10, 2026.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
On the default admin dashboard, the breadcrumb select's combobox input has no accessible name. axe reports label (critical). A screen-reader user reaching it hears no indication of what the control selects.
Measured on a blank install:
const inp = document.querySelector('.dashboard-breadcrumb-select input')
inp.id // "react-select-…-input"
inp.getAttribute('role') // "combobox"
inp.getAttribute('aria-label') // null
inp.getAttribute('aria-labelledby') // null
document.querySelector(`label[for="${inp.id}"]`) // null
inp.tabIndex // 0 — reachable, and unnamed
The control is the dashboard breadcrumb ReactSelect rendered by DashboardStepNav. Its call site passes no accessible name:
// @payloadcms/next/dist/views/Dashboard/Default/ModularDashboard/DashboardStepNav.js
<ReactSelect
className="dashboard-breadcrumb-select"
isClearable={false}
isSearchable={false}
onChange={handleChange}
options
placeholder={t("general:dashboard")}
value={{ label: t("general:dashboard"), value: "dashboard" }}
/>
There is no aria-label, aria-labelledby, or inputId bound to a visible label. react-select accepts aria-label / aria-labelledby and forwards them to the input, so supplying one at this call site would give the control a name. Note the placeholder and value.label are not a substitute — neither becomes the input's accessible name.
This needs no collections, fields, or configuration; it is on the dashboard of every install. A sibling defect on the same control — the dropdown indicator being focusable while aria-hidden — is filed separately.
Link to the code that reproduces this issue
https://github.com/rjbashar/payload-a11y-repro
Reproduction Steps
createdb payload_a11y_repro, thencp .env.example .envand setDATABASE_URI/PAYLOAD_SECRETpnpm installpnpm build && pnpm start— a production build; see the README note, aspnpm devdoes not hydrate the admin in this minimal app and the dashboard appears empty- Create the first user:
curl -X POST http://127.0.0.1:3210/api/users/first-register -H 'Content-Type: application/json' -d '{"email":"repro@example.test","password":"Repro-passw0rd!"}' - Sign in at
/admin/login, landing on/admin - Run the console snippet above, or
node verify.mjsfrom the repo
Restricted to this rule:
{ "id": "label", "impact": "critical", "nodes": 1, "targets": ["#react-select-_r_1_-input"] }
Which area(s) are affected?
area: ui, area: accessibility
Environment Info
payload 3.85.2
@payloadcms/next 3.85.2
@payloadcms/db-postgres 3.85.2
@payloadcms/richtext-lexical 3.85.2
next 16.3.4
react / react-dom 19.2.6
react-select 5.9.0 (transitive, via @payloadcms/ui)
node 26.0.0
axe-core 4.13.0
database PostgreSQL
Versions are pinned and the lockfile is committed, so the reproduction does not drift with @latest.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.