Skip to content

spec(ui): ComponentPropsMap['object-kanban'].grouping is z.unknown() while the board reads grouping.fields[0].field as its swimlane field — a padded or wrong-shaped grouping validates green and collapses the lanes #20831

Description

@objectstack-fleet

Filing-gate category: ① a product defect with a named landing site and a measured reach (class c: metadata an AI can write that validates green and renders wrong).
Reader who acts: the domain:spec seat that claims it (the spec row), then the objectui domain:ui seat for the mirror (a follow-up card, Blocked-by: this one, once a release carries it). Filed by the objectui domain:ui seat 1 (session_0122Knsowci76D2rBWReCzzZ) from the out-of-scope findings of objectstack-ai/objectui#7347 (PR objectstack-ai/objectui#11191).
Dedup: MCP search_issues on this repo for "object-kanban grouping z.unknown swimlane fallback ComponentPropsMap" → 3 hits, all closed and different (#18305 map/gantt/tree rows, #16503 kanban limit, #13692 empty-lane fallback); the channel answered with kanban cards, so the zero for this key is a reading. objectui: 435 issues updated since 2026-08-01 (open and closed) grepped for kanban + grouping → 0.

Seam: spec:ComponentPropsMap['object-kanban'].grouping → renderer:ObjectKanban (effectiveSwimlaneField)

The defect

  • Spec row. packages/spec/src/ui/component.zod.ts, ObjectKanbanPropsSchema (read at the 17.5.0 tag commit 0f6dcac5e9): grouping: z.unknown().optional().describe('View grouping config; its first field is the swimlane fallback'). The row is a strictObject, so grouping is a declared key, but its value is not judged at all.
  • Reader. objectui packages/plugin-kanban/src/ObjectKanban.tsx (objectui origin/main): const effectiveSwimlaneField = schema.swimlaneField || (schema.grouping?.fields?.[0]?.field);. The board looks the raw name up on every card.
  • The spec already has the shape. GroupingConfigSchema / GroupingFieldSchema (@objectstack/spec/ui) refuse a padded field name since spec: GroupingFieldSchema.field accepts a padded field name that three objectui readers bucket wrong — refuse non-trimmed names at the producer (ruling C on objectui#7347) #17360 (17.5.0) and judge the fields[] shape. The list-view row uses them; the kanban row does not.

Measured reach (objectui side)

On PR objectstack-ai/objectui#11191's branch, against the installed @objectstack/spec@17.5.0:

  • objectui validate (its safeValidateSchema, run from source) answers Schema is valid! for { type: 'object-kanban', objectName: 'account', grouping: { fields: [{ field: ' business_unit ' }] } }, and for grouping: 42. The same padded name on list-view is refused with a custom issue at grouping.fields[0].field.
  • The renderer outcome was measured earlier on A grouping field name with surrounding whitespace passes validation, is trimmed for $select, and then buckets every row into one (empty) group objectui#7347 (dev reading 5607077319, cited in that card's analysis): the kanban swimlane read buckets cards by the RAW padded name, which no record carries, so the lanes collapse with no error.
  • objectui's strict face refuses grouping on object-kanban by name (unrecognized_keys), which is narrower than this row. So today the two objectui faces and the spec give three different answers for the same key.

⛔ Not measured: os validate on a kanban node with a padded grouping. By construction z.unknown() accepts it; no run was taken.

What the fix looks like (a direction, not a ruling)

Type the row's grouping by reference to GroupingConfigSchema, so the padded name and the wrong shape are refused where every other grouping is refused (ADR-0078: no silently inert or unjudged metadata). If grouping on a kanban block has no real producer, retiring it in favour of swimlaneField is the other arm (enforce-or-remove, ADR-0049); that choice belongs to whoever grades this card. Either way, objectui then mirrors the row (a follow-up card on objectui).


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:specpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions