Skip to content

A type: 'form' action leaves the console shell for a bare /forms/:name page and ends on a generic "Thanks!" panel instead of the created record (observation) #7245

Description

@os-help

Found while browser-verifying #6739 / PR #7237 (the ruled type: 'modal'type: 'form' re-work of showcase_new_task). Filed separately, unfixed: it is pre-existing behavior that #6739's fix newly routes the showcase home page's primary CTA through, and it is not that card's scope.

Observation-class: nothing crashes, nothing is refused, and the record is created correctly. What is off is where the user ends up.

Measured

Real browser (Chromium 141), showcase booted with objectstack dev --ui --seed-admin, console served from packages/console/dist built by scripts/build-console.sh at the pinned .objectui-sha 09987b680d53801c79f67d969b14e9bb732b8a22. Full journey — start on the showcase home page, click the "Create Task" CTA:

home heading: ObjectStack Showcase
url after CTA click: http://localhost:3458/_console/forms/showcase_task.edit
dialogs: 0 | controls: 7
url after submit: http://localhost:3458/_console/forms/showcase_task.edit
RECORD QUERY total: 1
CREATED RECORD: {"id":"FUUCrcN0iO7hM1Dj","title":"#6739 browser-verified …","status":"todo","project":"SLJCKJy1_3RYDiI1"}

The record IS created. Two things about the surface it happens on:

1. The form route sits outside the console shell. In objectui apps/console/src/App.tsx (pinned SHA, line ~233) /forms/:name is a top-level route, a sibling of the app-shell routes rather than a child:

{/* Internal authed form — same renderer, different submit path. */}
Route path="/forms/:name" element={ ProtectedRoute + FormPage mode="internal" }

So the rendered page has no sidebar, no app navigation, no breadcrumb — screenshotted and confirmed visually, not inferred from the DOM. A user who clicks a record-create CTA on an app page is dropped onto an unchromed page with no way back except the browser's Back button.

2. The post-submit panel is the anonymous-form confirmation. FormPage resolves const behavior = loaded?.form?.submitBehavior ?? { kind: 'thank-you' }, so any form view that does not declare submitBehavior — including showcase_task.edit — renders:

Thanks!
Your submission has been received.

That is the right default for the public /f/:slug anonymous path the same component also serves. For an authed internal action it reads as a contact-form receipt: the user just created a Task and is told a submission was received, with no link to the record and no return to where they were.

Why it is worth recording

type: 'form' is the platform's validated, first-class way to open an object's form — the maintainer ruling on #6739 (2026-08-09) makes it the shape for this, retiring the type: 'modal' object fallback. So this is the surface every such action lands on, not a corner. showcase_log_time already ships on it; #6739 adds the home page's primary CTA and PR #6737's button.

The reference corpus therefore now teaches: "the sanctioned way to open a create form navigates out of your app and confirms with a generic receipt." Worth a decision even if the answer is "working as intended".

Shape of the question (not decided here)

  • Should ActionRunner.executeForm navigate at all, or render the form view in a dialog the way the modal path does? A route keeps deep-linking; a dialog keeps context.
  • If it stays a route, should /forms/:name in mode="internal" be nested inside the console shell layout?
  • Should an internal submit default to { kind: 'redirect' } to the created record rather than thank-you, leaving thank-you as the public-mode default? Or should showcase_task.edit simply declare a submitBehavior (a corpus fix rather than a platform one)?

The renderer code is in objectui (packages/core/src/actions/ActionRunner.ts executeForm, apps/console/src/App.tsx, apps/console/src/components/FormPage.tsx); filed here because the question is what the spec's type: 'form' contract should mean, and because #6739's ruling thread lives here. Re-route if the answer is purely a renderer change.

No pm:queue — observation, for triage to grade.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions