Skip to content

finding(plugin-timeline): an object-bound timeline with variant: "gantt" throws — calculateDateRange reads a row shape ObjectTimeline never composes #6655

Description

@os-sales

Filed unassigned, from work on #6355 (retiring the timeScale alias). Not caused by that change — see "Provenance" below.

What happens

Rendering ObjectTimeline with variant: 'gantt' and object-bound data throws:

RangeError: Invalid time value
at calculateDateRange packages/plugin-timeline/src/renderer.tsx:151
at TimelineRenderer packages/plugin-timeline/src/renderer.tsx:410

(line numbers at merge-base f241a4df4)

Why

The two timeline item shapes are not interchangeable, and this path crosses them.

ObjectTimeline maps each record to a feed item — flat, one item per record:

{title,time,startDate,endDate,description,variant,color,group,meta,_data}

calculateDateRange, on the gantt branch, reads the gantt row shape instead — a row that owns a nested items array:

constallDates=items.flatMap((row)=>(row.items||[]).flatMap((item)=>[item.startDate,item.endDate]));

For ObjectTimeline's output every row.items is undefined, so allDates is empty. Math.min() over an empty list is Infinity, and new Date(Infinity).toISOString() throws. There is no guard and no diagnostic — the component simply throws during render.

Why it matters

ObjectTimeline deliberately resolves an axis scale (timelineConfig?.scale ?? schema.scale) and composes it into the schema it hands the renderer. That axis is a gantt-only concern — the vertical and horizontal variants are sequential feeds with no time axis. So the object-bound path carries configuration for exactly the variant it cannot render: an author who sets variant: gantt on an object-bound timeline gets a crash rather than a chart, and the scale option that path plumbs through is unreachable in practice.

Provenance — this predates #6355

Observed while writing #6355's pins. Both halves of the crash are byte-identical to the merge base, verified with git diff:

  • calculateDateRange in renderer.tsx — untouched (0 changed lines matching the function or its body);
  • ObjectTimeline's record-to-item mapping — untouched.

#6355 changes only which KEY the resolved axis is composed under (timeScale to scale). #6355's own pin therefore renders variant: 'vertical' deliberately, so it does not couple to this defect.

Related, but not the same card

#6356 records that TimelineSchema.items has no declared element type and that there are two of them. That is the declaration half of the same two-shapes fact. This is the runtime half: declaring the element type would not stop ObjectTimeline from composing the wrong one of the two for gantt, so this is not fixed by closing #6356.

For triage — two directions, both plausible

  1. Make it work: ObjectTimeline composes gantt ROWS for variant: gantt, grouping records into rows (groupByField is already resolved on that path and is the obvious grouping key).
  2. Make it refuse loudly: the object-bound path rejects variant: gantt with a real diagnostic until (1) exists — no crash, and no silently-inert scale option either.

Which one is right depends on whether object-bound gantt is a capability the product wants now; that is a maintainer call, not a mechanical fix, which is why this is filed rather than fixed.

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatchedpriority:p1

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions