Skip to content

'timeline' is registered twice, and the bare-name fallback resolves to the later registration by module-evaluation order #6353

Description

@os-support-ai

Found while working #6170 (PR #6352); out of that card's scope, filed unassigned.

The fact

packages/plugin-timeline calls ComponentRegistry.register with the key 'timeline' twice:

site component namespace
src/renderer.tsx:498 TimelineRenderer (presentational) plugin-timeline
src/index.tsx:366 ObjectTimelineRenderer (object-bound) view

Both are namespaced, neither passes skipFallback, so each also claims the bare timeline key (Registry.ts:246-266).

index.tsx:300 is export * from './renderer';, which is requested before the import at line 307, so renderer.tsx evaluates first and claims bare timelineTimelineRenderer. The call at index.tsx:366 then overwrites it. So a node authored type: 'timeline' resolves to ObjectTimelineRenderer, which delegates inward to TimelineRenderer (ObjectTimeline.tsx:443).

Why it is worth a card

The outcome is probably intended — the object-bound wrapper is the right entry point, and it does reach the presentational renderer. What is not fine is how it is decided: by the order two module requests happen to appear in one file. Reorder those two lines and type: 'timeline' silently becomes the presentational renderer, which reads none of the object-bound keys — an authored timeline would stop fetching, with no error.

Registry.register carries a collision guard for exactly this shape, whose message names the remedy:

Component "timeline" bare-name fallback is being overwritten by "view:timeline". If this is intentional keep going; otherwise register "view:timeline" with { skipFallback: true } so it doesn't claim the bare "timeline" key.

So the repo already believes this needs a deliberate answer. Either declare the intent (and pin it), or give the presentational registration skipFallback: true.

Worth checking whether other plugins have the same double-claim; the guard warns at runtime only, so nothing fails CI today.

Reproduce

grep -n "ComponentRegistry.register" packages/plugin-timeline/src/*.tsx
sed -n '296,310p' packages/plugin-timeline/src/index.tsx
sed -n '242,268p' packages/core/src/registry/Registry.ts

Refs: #6170, PR #6352. Related: #5106 (the doc-types gate never judges the namespace half of a registration row).

Metadata

Metadata

Assignees

Labels

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

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions