Claude Code writes several headerless session-log lines with no timestamp field — last-prompt, ai-title, custom-title. A headless run (claude -p ...) produces them every time, and long sessions accumulate hundreds of them (a recent real session on disk had ~300). toolpath-claude turns each preamble line into a synthetic claude-preamble-N step and copies the missing timestamp through as "timestamp": "".
The schema forbids that value: $defs/timestamp in crates/toolpath/schema/toolpath.schema.json is format: date-time, and a step that fails it makes the containing path fail $defs/pathOrRef — so a format-asserting validator rejects the whole document with a oneOf failure at /paths/0.
Repro:
claude -p "say hi" # in any project
path p import claude --project <dir> --all --no-cache > doc.json
# doc.json now contains steps like:
# {"step": {"id": "claude-preamble-2", "timestamp": "", ...}}
Two bugs compound here:
- The importer emits the invalid value. The fix belongs in
toolpath-claude: when a preamble line has no timestamp, fall back to the timestamp of an adjacent entry — the message the line references via leafUuid (real last-prompt lines carry one) or messageId, else the previous preamble line, else the session's first message timestamp. The raw line is preserved verbatim in the step's structural change, so the fallback must not leak back into projected JSONL.
path p validate doesn't catch it. JSON Schema draft 2020-12 treats format as annotation-only unless the validator opts in, and ours never did — so p validate reports these documents as Valid and the invalid timestamps only surface downstream, on format-asserting consumers. Validation should assert the formats the schema declares (date-time on step timestamps, uri on meta.kind / path-ref $ref / signature href).
Claude Code writes several headerless session-log lines with no
timestampfield —last-prompt,ai-title,custom-title. A headless run (claude -p ...) produces them every time, and long sessions accumulate hundreds of them (a recent real session on disk had ~300).toolpath-claudeturns each preamble line into a syntheticclaude-preamble-Nstep and copies the missing timestamp through as"timestamp": "".The schema forbids that value:
$defs/timestampincrates/toolpath/schema/toolpath.schema.jsonisformat: date-time, and a step that fails it makes the containing path fail$defs/pathOrRef— so a format-asserting validator rejects the whole document with aoneOffailure at/paths/0.Repro:
Two bugs compound here:
toolpath-claude: when a preamble line has no timestamp, fall back to the timestamp of an adjacent entry — the message the line references vialeafUuid(reallast-promptlines carry one) ormessageId, else the previous preamble line, else the session's first message timestamp. The raw line is preserved verbatim in the step's structural change, so the fallback must not leak back into projected JSONL.path p validatedoesn't catch it. JSON Schema draft 2020-12 treatsformatas annotation-only unless the validator opts in, and ours never did — sop validatereports these documents as Valid and the invalid timestamps only surface downstream, on format-asserting consumers. Validation should assert the formats the schema declares (date-timeon step timestamps,urionmeta.kind/ path-ref$ref/ signaturehref).