You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Record create: a date typed in an invalid form (13/45/2026) is silently dropped, and the record saves with an empty Due Date and a success toast #27483
Found in the 18.3.0 release-candidate browser walkthrough (wave anchor #27377, card W3-UX), at framework main @ c4c515ad, Console built in-repo from the same commit.
Repro (fresh boot)
Boot examples/app-showcase with --seed-admin and sign in as admin. Viewport 1440×900.
Open Showcase → Tasks and click New.
Enter Title Walkthrough task and pick a Project.
Type 13/45/2026 into Due Date. The input shows exactly that text.
Click Create.
Expected
The date field is marked invalid ("Enter a valid date") and the dialog stays open, as it does for a missing required field.
Actual
The toast says Task "Walkthrough task" created. The saved row has due_date: null (GET /api/v1/data/showcase_task/ID). The typed value disappears with no message, so the user believes the date was saved.
Read fresh. An invalid typed date (13/45/2026) on record create is silently dropped. The record saves with an empty Due Date and a success toast. A silent drop of an authored value: p2.
Mark an unparseable date invalid through the form's existing field validation, as a missing required field is. No silent null.
Claim: PM loop round 1 · 2026-10-29T13:19Z
Session: session_01Utp6CY2n1JmZZKrHgtp9jC (seat; implementation by a card thread, mode:thread)
Account: os-bill
Branch: claude/project-thread-t6m105 (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
Worktree: objectstack-issue-27483
Domain: domain:ui
Seat: domain:ui#2
File surface: ui/packages/fields/src/widgets/** (date picker + widget types), the form renderer that mounts widgets (ui/packages/components/src/renderers/form/form.tsx and/or ui/packages/plugin-form/src/ObjectForm.tsx), i18n only if a key is missing, tests beside, a changeset (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: yes (widening) — corrected by the seat from the diff: the new optional onInvalidInputChange key on FieldWidgetComponentProps, exported from @object-ui/fields; owes a TIER_DEFAULT declaration review at the final head
Metadata-protocol: none (expected; the dev measures from the diff)
Responsibility: ui/packages/fields date picker + the form renderer's validation | none (the form's required-field validation does not see the picker's bad text) | every user typing a date on a create/edit form, today
Thread-read: 6496267646
Premise: holds — on origin/mainee9a8d6eDatePickerField sets only local badText for an unparseable date and never reports it to the form (no outbound validity channel in FieldWidgetComponentProps)
Serial constraints cleared: none on fields/src/widgets/date-picker/**; ObjectForm.tsx / form.tsx are shared with this seat's #27247 (different regions: submit bar vs field validation): ordinary concurrency, later lander merges main
Dispatch order: /mnt/project-files/ui-seat2/dispatch-27483.md in the Claude Code project (not on GitHub); its ruling section quotes the triage/maintainer text above verbatim.
{
"issue": 27483,
"status": "done",
"branch": "claude/project-thread-t6m105",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27623",
"session": "session_01Utp6CXAtdK85r4832Kydbf (card thread, mode:thread; seat session_01Utp6CY2n1JmZZKrHgtp9jC)",
"premise_still_valid": true,
"summary": "Premise measured true on origin/main 556f3230: TemporalPicker's commitText sets only local badText for text parseLocaleDateText rejects, never calls onChange, and FieldWidgetComponentProps had no outbound validity channel. Added an optional onInvalidInputChange(message | null) widget prop (types.ts, toHostProps HOST_PLUMBING_KEYS); DatePickerField/DateTimePickerField report on change, withdraw on clear/valid commit/unmount, report nothing while readonly, and leave the message text to the host when one takes the callback. The form renderer (components form.tsx) holds the message per field and refuses through a first rules.validate entry, invalidInput, triggered at once on report; withdrawal clears only that error; stripRegisteredFieldProps forwards the callback to date/datetime only. time is a native input with its own path, untouched. ObjectForm.tsx needed no change (all plugin-form hosts render through the one form renderer).",
"tests": "head c4826848 (readings at bc5108de, after the one merge of main; c4826848 retypes the two new test files only): pnpm --dir ui exec vitest run --maxWorkers=2 packages/fields/ packages/components/ under the lock -> Test Files 734 passed | 2 skipped, Tests 8683 passed | 31 skipped, VERDICT command-exit 0 (pre-merge 731 files / 8654 tests, exit 0). At c4826848: fields + components type-check exit 0; the four pin files 33/33 passed. New: fields/src/__tests__/date-picker-invalid-text-blocks-submit-27483.test.tsx (5, real form renderer + production picker registration: 13/45/2026 shows the form message + aria-invalid, Create refused, onSubmit never called; correct -> saves 2026-10-20; clear -> optional empty saves; valid control; datetime refuses), components form-invalid-input-refuses-submit-27483.test.tsx (3, probe), DatePickerField-12622.test.tsx +3 (existing 'not written, and says so' pin kept unchanged). Ablation via scripts/ablation-replace.mjs (vitest aliases @object-ui/components to src, no build leg): form validator forced to pass -> 4 red / 20 green, restored blob c3d119a7bf03; picker report call removed -> 5 red / 16 green, restored blob 556b44a4b738.",
"gates": "dispatch-gates --commands at c4826848: 34 families; every one run, `COMMAND :: exit 0` for all 34 (pnpm check:type-check-debt and pnpm --dir ui exec vitest run scripts/ ran under the verify lock). dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED. node scripts/check-sdui-manifest.mjs exit 0 and --self-test exit 0. ui pnpm check:new-line-citations: 0 new. eslint on the 7 changed ui files: 0 errors, no warning on added lines. Earlier reading at bc5108de: type-check-debt exit 3 (queue timeout) then 0 under the lock; ui scripts suite one 15 s timeout beside the package run, then green alone. CI families: PR check-runs in progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"line_budget": "8 files, +417 / -3 vs merge base (dispatch-gates changed-lines reading), under the 3000 human-merge threshold",
"files_changed": [".changeset/27483-invalid-typed-date-refuses-submit.md", "ui/packages/components/src/renderers/form/form.tsx", "ui/packages/components/src/renderers/form/__tests__/form-invalid-input-refuses-submit-27483.test.tsx", "ui/packages/fields/src/widgets/date-picker/DatePickerField.tsx", "ui/packages/fields/src/widgets/date-picker/DatePickerField-12622.test.tsx", "ui/packages/fields/src/widgets/types.ts", "ui/packages/fields/src/widgets/toHostProps.ts", "ui/packages/fields/src/__tests__/date-picker-invalid-text-blocks-submit-27483.test.tsx"],
"deviations": ["One merge-commit conflict in form.tsx stripRegisteredFieldProps against main's record-currency allow-list line; both lines kept.", "The PR body cites readings at bc5108de and states the c4826848 deltas; it is written once and not patched.", "Harness post-PR assignee/reviewer step skipped per the maintainer's routing rule; the relay read-back shows no assignees.", "One commit title on the branch names the card number (test retyping commit); no closing keyword."],
"mcp_calls": "3 — mcp__github__issue_read (get, get_comments) x2 read-only; mcp__claude-code-remote__subscribe_pr_activity x1 (PR event subscription, not a GitHub write)",
"api_writes": "2 — relay pr_create (repository_dispatch -> POST /repos/objectstack-ai/objectstack/pulls, draft, read-back identical 7459 bytes); this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27483/comments). git pushes not counted.",
"open_questions": [],
"out_of_scope_findings": ["carrier: none · noted, not filed — FieldEditWidget (grid / record-page inline edit), ActionParamDialog and BulkActionDialog pass no onInvalidInputChange, so there the picker shows its own notice but does not block the host's save; not reproduced, recorded in the PR's Acceptance notes. dedupe words: inline edit invalid date, action param date notice, onInvalidInputChange host"]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 能用的表单 | none | P②
Triage: p2 ·
domain:ui·area:records· 2026-10-29T12:09Z⛔ Not a claim.
bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
Claim: PM loop round 1 · 2026-10-29T13:19Z
Session:
session_01Utp6CY2n1JmZZKrHgtp9jC(seat; implementation by a card thread,mode:thread)Account:
os-billBranch:
claude/project-thread-t6m105(the card thread's harness push branch, self-reported — the measured platform exception toclaude/issue-N-slug)Worktree:
objectstack-issue-27483Domain:
domain:uiSeat:
domain:ui#2File surface:
ui/packages/fields/src/widgets/**(date picker + widget types), the form renderer that mounts widgets (ui/packages/components/src/renderers/form/form.tsxand/orui/packages/plugin-form/src/ObjectForm.tsx), i18n only if a key is missing, tests beside, a changeset (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: yes (widening) — corrected by the seat from the diff: the new optional
onInvalidInputChangekey onFieldWidgetComponentProps, exported from@object-ui/fields; owes a TIER_DEFAULT declaration review at the final headMetadata-protocol: none (expected; the dev measures from the diff)
Responsibility:
ui/packages/fieldsdate picker + the form renderer's validation | none (the form's required-field validation does not see the picker's bad text) | every user typing a date on a create/edit form, todayThread-read: 6496267646
Premise: holds — on
origin/mainee9a8d6eDatePickerFieldsets only localbadTextfor an unparseable date and never reports it to the form (no outbound validity channel inFieldWidgetComponentProps)Serial constraints cleared: none on
fields/src/widgets/date-picker/**;ObjectForm.tsx/form.tsxare shared with this seat's #27247 (different regions: submit bar vs field validation): ordinary concurrency, later lander mergesmainDispatch order:
/mnt/project-files/ui-seat2/dispatch-27483.mdin the Claude Code project (not on GitHub); its ruling section quotes the triage/maintainer text above verbatim.Generated by Claude Code
test(fields,components): the #27483 pins type their probe and registr…
objectstack-fleet commentedon Oct 29, 2026
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
os-dev-report
{ "issue": 27483, "status": "done", "branch": "claude/project-thread-t6m105", "pr": "https://github.com/objectstack-ai/objectstack/pull/27623", "session": "session_01Utp6CXAtdK85r4832Kydbf (card thread, mode:thread; seat session_01Utp6CY2n1JmZZKrHgtp9jC)", "premise_still_valid": true, "summary": "Premise measured true on origin/main 556f3230: TemporalPicker's commitText sets only local badText for text parseLocaleDateText rejects, never calls onChange, and FieldWidgetComponentProps had no outbound validity channel. Added an optional onInvalidInputChange(message | null) widget prop (types.ts, toHostProps HOST_PLUMBING_KEYS); DatePickerField/DateTimePickerField report on change, withdraw on clear/valid commit/unmount, report nothing while readonly, and leave the message text to the host when one takes the callback. The form renderer (components form.tsx) holds the message per field and refuses through a first rules.validate entry, invalidInput, triggered at once on report; withdrawal clears only that error; stripRegisteredFieldProps forwards the callback to date/datetime only. time is a native input with its own path, untouched. ObjectForm.tsx needed no change (all plugin-form hosts render through the one form renderer).", "tests": "head c4826848 (readings at bc5108de, after the one merge of main; c4826848 retypes the two new test files only): pnpm --dir ui exec vitest run --maxWorkers=2 packages/fields/ packages/components/ under the lock -> Test Files 734 passed | 2 skipped, Tests 8683 passed | 31 skipped, VERDICT command-exit 0 (pre-merge 731 files / 8654 tests, exit 0). At c4826848: fields + components type-check exit 0; the four pin files 33/33 passed. New: fields/src/__tests__/date-picker-invalid-text-blocks-submit-27483.test.tsx (5, real form renderer + production picker registration: 13/45/2026 shows the form message + aria-invalid, Create refused, onSubmit never called; correct -> saves 2026-10-20; clear -> optional empty saves; valid control; datetime refuses), components form-invalid-input-refuses-submit-27483.test.tsx (3, probe), DatePickerField-12622.test.tsx +3 (existing 'not written, and says so' pin kept unchanged). Ablation via scripts/ablation-replace.mjs (vitest aliases @object-ui/components to src, no build leg): form validator forced to pass -> 4 red / 20 green, restored blob c3d119a7bf03; picker report call removed -> 5 red / 16 green, restored blob 556b44a4b738.", "gates": "dispatch-gates --commands at c4826848: 34 families; every one run, `COMMAND :: exit 0` for all 34 (pnpm check:type-check-debt and pnpm --dir ui exec vitest run scripts/ ran under the verify lock). dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED. node scripts/check-sdui-manifest.mjs exit 0 and --self-test exit 0. ui pnpm check:new-line-citations: 0 new. eslint on the 7 changed ui files: 0 errors, no warning on added lines. Earlier reading at bc5108de: type-check-debt exit 3 (queue timeout) then 0 under the lock; ui scripts suite one 15 s timeout beside the package run, then green alone. CI families: PR check-runs in progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "line_budget": "8 files, +417 / -3 vs merge base (dispatch-gates changed-lines reading), under the 3000 human-merge threshold", "files_changed": [".changeset/27483-invalid-typed-date-refuses-submit.md", "ui/packages/components/src/renderers/form/form.tsx", "ui/packages/components/src/renderers/form/__tests__/form-invalid-input-refuses-submit-27483.test.tsx", "ui/packages/fields/src/widgets/date-picker/DatePickerField.tsx", "ui/packages/fields/src/widgets/date-picker/DatePickerField-12622.test.tsx", "ui/packages/fields/src/widgets/types.ts", "ui/packages/fields/src/widgets/toHostProps.ts", "ui/packages/fields/src/__tests__/date-picker-invalid-text-blocks-submit-27483.test.tsx"], "deviations": ["One merge-commit conflict in form.tsx stripRegisteredFieldProps against main's record-currency allow-list line; both lines kept.", "The PR body cites readings at bc5108de and states the c4826848 deltas; it is written once and not patched.", "Harness post-PR assignee/reviewer step skipped per the maintainer's routing rule; the relay read-back shows no assignees.", "One commit title on the branch names the card number (test retyping commit); no closing keyword."], "mcp_calls": "3 — mcp__github__issue_read (get, get_comments) x2 read-only; mcp__claude-code-remote__subscribe_pr_activity x1 (PR event subscription, not a GitHub write)", "api_writes": "2 — relay pr_create (repository_dispatch -> POST /repos/objectstack-ai/objectstack/pulls, draft, read-back identical 7459 bytes); this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27483/comments). git pushes not counted.", "open_questions": [], "out_of_scope_findings": ["carrier: none · noted, not filed — FieldEditWidget (grid / record-page inline edit), ActionParamDialog and BulkActionDialog pass no onInvalidInputChange, so there the picker shows its own notice but does not block the host's save; not reproduced, recorded in the PR's Acceptance notes. dedupe words: inline edit invalid date, action param date notice, onInvalidInputChange host"] }objectstack-fleet commentedon Oct 29, 2026
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
ACCEPT → PR #27623 comment 6501365271 (head
81611c8a); contract review (declaration, TIER_DEFAULT) PASS 6501038827; landing through the merge queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
Landed · 2026-10-29T16:02Z
efa2915e4c2dc1d5bd09bedbd4eef9bc31cb9fe6completedby the PR'sFixeslineState:
pm:dispatchedremoved; the assignee stays as the record of who carried it.Generated by Claude Code