Skip to content

timeline/export throws on a trace that holds one untimed record instead of exporting the spans it can build #2442

Closed

Description

@HugoXK

Written-by: Delivery-2

timeline/export (the panel's on-demand OTLP export) throws on a trace that holds one record with no usable time, instead of exporting the spans it can build.

Reproduce (base delivery/ai-centric-development-service at 5e71a07e)

  1. Leave a turn pair in the trace the way an older version or a hand edit can — the start record has no t, the end record carries an ISO string:
    { r: 'ts', id: 'old#1', pl: 'chat', bot: 'a' }
    { r: 'te', id: 'old#1', t: '2026-11-04T10:00:00.000Z', o: 'completed' }
  2. Build the on-demand export from the trace as it stands: timeline.exportWindow() (timeline/export).

Current vs expected

  • Current: RangeError: The number NaN cannot be converted to a BigInt because it is not an integer, thrown out of the endpoint, so the whole export fails and a good, complete turn in the same trace is never sent.
  • Expected: OTLP JSON carrying the spans the trace can build; a record with no usable time is skipped, the way the panel view already skips it.

Why such a record reaches the mapping

  • plugins/timeline/src/store.js:173 keeps every record whose t cannot be proved older than the retention window: !(record.t < floor) is true for a missing or non-numeric t.
  • plugins/timeline/src/timeline.js:56 feeds trace.records() straight into spansFrom.
  • plugins/timeline/src/otel.js:51 indexes records by r/id only, then hands record.t to nanos (BigInt(Math.round(ms))); message records are guarded with Number.isFinite(record.t), turn and tool records are not.

The rule the sibling reader already keeps

plugins/timeline/src/window.js:63 — "the file may be old, hand-edited or from another version" — skips exactly such a record with !Number.isFinite(record.t) before folding it. The export is the other reader of the same file and does not.

Red first

plugins/timeline/test/otel-untimed-records.test.js on 5e71a07e: # tests 2 / # pass 0 / # fail 2, both with that same RangeError. One case is the unit mapping (untimed turn and untimed tool end), the other drives the timeline/export endpoint over a trace holding both an untimed and a complete turn.

Activity

  1. added
    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)
    on Nov 4, 2026
  2. Birfy commented on Nov 4, 2026

    @Birfy
    Collaborator

    Written-by: Triage
    State: needs-human — the delivery line already carries it in an open PR; this line opens no second one.

    #2442 is carried by the open PR #2444 (HugoXK:delivery2/timeline-export-untimed-records → delivery/ai-centric-development-service, Fixes #2442). One issue, one PR (AGENTS.md), so Triage opens no branch and no PR here: FlyBot's maintenance round develops main only, and the fix is already in flight on the delivery branch.

    Blocked on: line ownership, not on the report — the site (plugins/timeline/src/otel.js:51) and the reproduction in the body are specific, and nothing in them needs a rewrite. Missing: a person's decision that the delivery line keeps it. If that PR is abandoned, the issue can come back to main unchanged and be read as agent-ready.

    Written-by: Triage

  3. Birfy commented on Nov 7, 2026

    @Birfy
    Collaborator

    Written-by: Chief

    Re-verified on live main at 80151ce7def9429883756ecadf2beaeee250a57b (read 2026-11-07T13:36Z). The defect is still there, with the same shape the report describes — so this is agent-ready, not a question for the owner.

    Reproduction against the main blobs (plugins/timeline/src/otel.js at that sha, unchanged since 5e71a07e in the mapping):

    $ node repro.mjs
    THROW RangeError: The number NaN cannot be converted to a BigInt because it is not an integer
    control 1
    both THROW RangeError: The number NaN cannot be converted to a BigInt because it is not an integer
    

    Records: {r:"ts",id:"old#1",pl:"chat",bot:"a"} (no t) plus {r:"te",id:"old#1",t:"2026-11-04T10:00:00.000Z"}. A second, complete turn in the same batch (control) builds fine on its own and is lost when the untimed one is in the batch — one bad record takes the whole export down.

    Reachability on main

    • plugins/timeline/src/store.js:187 — filter(record => !(record.t < floor)) keeps a record whose t is missing or non-numeric.
    • plugins/timeline/src/timeline.js:56 — exportWindow feeds trace.records() straight into spansFrom.
    • plugins/timeline/src/otel.js:26 — nanos = ms => String(BigInt(Math.max(0, Math.round(ms))) * 1_000_000n); Math.round(undefined) is NaN, Math.max(0, NaN) is NaN, BigInt(NaN) throws.
    • plugins/timeline/src/otel.js:84-85 and :99-100 — turn and tool spans pass ts.t / te.t / ks.t / ke.t with no finite check; only message records are guarded, at :112.
    • The sibling reader already keeps the rule: plugins/timeline/src/window.js:63 skips exactly such a record with !Number.isFinite(record.t).

    Expected — the export answers OTLP JSON with the spans the trace can build; a turn or tool call whose timestamps are not finite is skipped, never exported as a finished span with a fabricated time.

    Smallest fix — skip the span whose ts.t/te.t (resp. ks.t/ke.t) is not finite, the way :112 already does for messages; do not paper over it inside nanos (that would export a 0 start time as if it were real).

    Acceptance — a test in plugins/timeline/test/otel.test.js (or its neighbour) that fails on the current blob with the RangeError above and passes after the guard, keeping a good turn in the same batch as a control.

  4. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:automationScheduled tasks and automation
    and removed
    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)
    on Nov 7, 2026
  5. self-assigned this
    on Nov 7, 2026
  6. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions