Hmbown/CodeWhale · error · Error
Missing . Times must be numeric milliseconds.
Error message
Missing ${field}. Times must be numeric milliseconds. What it means
The `number` helper in pet/src/core/ingest.ts:66 throws when a time field is undefined/null while the `optional` flag is false — i.e. the field is required. startTime is validated as required via number(a.startTime,'startTime',false).
Solutions
- Provide a numeric millisecond startTime on every ingested record
- Check the upstream exporter mapping for null/undefined startTime
- Default to span start if your source has it under a different key
Example fix
// before
{name:'op', traceId:'t1', id:'e1'}
// after
{name:'op', traceId:'t1', id:'e1', startTime: 1700000000000} Defensive patterns
Strategy: type-guard
Validate before calling
if (rec.startTime===undefined||rec.startTime===null) throw new Error('startTime required before ingest'); Type guard
const hasStartTime = (r:any): r is {startTime:number} & Record<string,unknown> => typeof r?.startTime==='number' && Number.isFinite(r.startTime); Try / catch
try { ingest(records); } catch (e) { if (/Missing .*\. Times must be numeric/.test(e.message)) { /* repair or drop the record named by field/index */ } else throw e; } Prevention
- Require startTime in your record schema/validation layer
- Map OTLP startTimeUnixNano explicitly to startTime
- Reject null-filled records at export time
When it happens
Trigger: Calling the OTLP/trace ingest path with a record missing startTime (number(v,field,false)); nonnegative fields routed through required mode.
Common situations: OTLP span JSON missing startTimeUnixNano mapped to startTime; a transform dropping the field when null; hand-written test fixtures omitting startTime.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- must be nonnegative.
- Invalid : expected a finite, safely representable number.
- Record requires nonempty id, traceId, and name.
- Duplicate event identity
- Every OTLP span requires traceId and spanId.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/c72690210c83b0c8.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/core/ingest.ts:66
}
if (value && typeof value === 'object') seen.delete(value);
return hook ? hook(out, path) : out;
}
export function privacyEvent(e: WhaleEvent, mode: PrivacyMode): WhaleEvent {
if (mode === 'metadata') {
const { payload: _payload, raw: _raw, ...rest } = e;
return { ...rest, links: e.links?.map(link=>({traceId:link.traceId,spanId:link.spanId})), attributes: Object.fromEntries(Object.entries(e.attributes).filter(([k, v]) =>
SAFE_META.test(k) && (typeof v !== 'object' || v === null)
|| ['whalesong.container', 'codewhale.container', 'whalesong.waiting'].includes(k) && typeof v === 'boolean'
// Relative timestamps can be negative before the importer rebases them.
|| k === 'whalesong.error_onset_ms' && typeof v === 'number' && Number.isFinite(v))) };
}
return e;
}
function number(v: unknown, field: string, optional = true): number | undefined {
if (v === undefined || v === null) {
if (optional) return undefined;
throw new Error(`Missing ${field}. Times must be numeric milliseconds.`);
}
if (typeof v !== 'number' || !Number.isFinite(v) || Math.abs(v) > Number.MAX_SAFE_INTEGER) throw new Error(`Invalid ${field}: expected a finite, safely representable number.`);
return v;
}
function nonnegative(v: unknown, field: string): number | undefined {
const n = number(v, field); if (n !== undefined && n < 0) throw new Error(`${field} must be nonnegative.`); return n;
}
function numericAttr(v: unknown): number | undefined {
if (v === undefined || v === null || v === '') return undefined;
const n = Number(v); return Number.isFinite(n) && n >= 0 ? n : undefined;
}
export function categoryFor(name: string, a: Obj): Category {
const explicit = a['whalesong.category'] ?? a.category;
if (CATEGORIES.includes(explicit)) return explicit;
const n = name.toLowerCase(), op = String(a['gen_ai.operation.name'] ?? '').toLowerCase();
if (/exception|^error\b/.test(n)) return 'error';
if (/spawn|fork|subagent/.test(n) || op === 'invoke_agent') return 'agent';
if (/message\.send|handoff|agent\.message/.test(n)) return 'communication';View on GitHub (pinned to 433685b202)