Problem
README.md states the web app's browser support floor as Chrome 90+, Firefox 88+, Safari 14+, Edge 90+. Object.hasOwn was standardized in ES2022 and only ships natively in Chrome 93+, Firefox 92+, Safari 15.4+ — narrower than the documented floor. On any browser inside the documented-but-unsupported gap (Chrome 90–92, Firefox 88–91, Safari 14–15.3), calling Object.hasOwn throws TypeError: Object.hasOwn is not a function.
This is not a new regression from any single PR — it is a pre-existing, systemic mismatch:
vite.config.ts sets build.target: 'es2022' with polyfill: false (present since at least 21a17d9d, 2026-04-18) — the build explicitly does not polyfill runtime APIs for older targets.
services/appBootstrap.ts's normalizeEntityCollection (introduced b0286f0a, 2026-08-31) calls Object.hasOwn unconditionally on the app-bootstrap hot path (every load that has any character/world entities) — this alone already makes Object.hasOwn a hard runtime requirement, independent of any later call site.
- Several other production call sites now also use
Object.hasOwn: features/project/coreBoundaryAdapter.ts, features/project/adapters.ts, features/project/thunks/projectManagementThunks.ts, components/manuscript/ManuscriptEditor.tsx, features/project/projectSchemaVersion.ts.
Surfaced by chatgpt-codex-connector on PR #619 against features/project/projectSchemaVersion.ts's use in classifyProjectVersionFromObject; verified against services/appBootstrap.ts git history to confirm the gap predates and is broader than that PR, so it was not fixed narrowly there (see PR #619's thread reply).
Fix (needs a maintainer decision — pick one)
- Raise the documented floor — update
README.md to Chrome 93+ / Firefox 92+ / Safari 15.4+ (matching what the codebase already requires in practice), or
- Lower the actual requirement — replace every
Object.hasOwn(x, k) call site with Object.prototype.hasOwnProperty.call(x, k) (identical own-property semantics, ES5-safe, works for null-prototype objects too) and add a lint/CI guard against reintroducing Object.hasOwn if the documented floor is meant to stay at Chrome 90/Firefox 88/Safari 14.
Scope
All production call sites listed above; not just projectSchemaVersion.ts.
Problem
README.mdstates the web app's browser support floor as Chrome 90+, Firefox 88+, Safari 14+, Edge 90+.Object.hasOwnwas standardized in ES2022 and only ships natively in Chrome 93+, Firefox 92+, Safari 15.4+ — narrower than the documented floor. On any browser inside the documented-but-unsupported gap (Chrome 90–92, Firefox 88–91, Safari 14–15.3), callingObject.hasOwnthrowsTypeError: Object.hasOwn is not a function.This is not a new regression from any single PR — it is a pre-existing, systemic mismatch:
vite.config.tssetsbuild.target: 'es2022'withpolyfill: false(present since at least21a17d9d, 2026-04-18) — the build explicitly does not polyfill runtime APIs for older targets.services/appBootstrap.ts'snormalizeEntityCollection(introducedb0286f0a, 2026-08-31) callsObject.hasOwnunconditionally on the app-bootstrap hot path (every load that has any character/world entities) — this alone already makesObject.hasOwna hard runtime requirement, independent of any later call site.Object.hasOwn:features/project/coreBoundaryAdapter.ts,features/project/adapters.ts,features/project/thunks/projectManagementThunks.ts,components/manuscript/ManuscriptEditor.tsx,features/project/projectSchemaVersion.ts.Surfaced by chatgpt-codex-connector on PR #619 against
features/project/projectSchemaVersion.ts's use inclassifyProjectVersionFromObject; verified againstservices/appBootstrap.tsgit history to confirm the gap predates and is broader than that PR, so it was not fixed narrowly there (see PR #619's thread reply).Fix (needs a maintainer decision — pick one)
README.mdto Chrome 93+ / Firefox 92+ / Safari 15.4+ (matching what the codebase already requires in practice), orObject.hasOwn(x, k)call site withObject.prototype.hasOwnProperty.call(x, k)(identical own-property semantics, ES5-safe, works for null-prototype objects too) and add a lint/CI guard against reintroducingObject.hasOwnif the documented floor is meant to stay at Chrome 90/Firefox 88/Safari 14.Scope
All production call sites listed above; not just
projectSchemaVersion.ts.