{"record":{"id":"ba620b2a778ae8ba","repo":"Hmbown/CodeWhale","slug":"invalid-failure-observation-time","errorCode":null,"errorMessage":"Invalid failure observation time.","messagePattern":"Invalid failure observation time\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":625,"sourceCode":"    if (f.query) {\n        const q = f.query.toLowerCase();\n        // Search is deliberately content-aware but runs only over locally retained fields.\n        if (![e.name, e.id, e.agentId, e.model, e.tool, e.provider, e.category,\n            JSON.stringify(e.attributes), JSON.stringify(e.payload), JSON.stringify(e.raw)].filter(Boolean).join(' ').toLowerCase().includes(q))\n            return false;\n    }\n    return true;\n}\nconst durationOf = (e) => Math.max(0, e.endTime - e.startTime);\nexports.durationOf = durationOf;\n/** An explicit failure receipt can arrive after a span began or ended. Keep\n * its timestamp distinct from the operation onset in every signal view. */\nfunction errorOnsetOf(e) {\n    const time = e.attributes['whalesong.error_onset_ms'];\n    if (time === undefined)\n        return e.startTime;\n    if (typeof time !== 'number' || !Number.isFinite(time) || time < e.startTime)\n        throw new Error('Invalid failure observation time.');\n    return time;\n}\nfunction stableHash(text, seed = 2166136261) {\n    let h = seed;\n    for (let i = 0; i < text.length; i++) {\n        h ^= text.charCodeAt(i);\n        h = Math.imul(h, 16777619);\n    }\n    return h >>> 0;\n}\nfunction quantile(a, q) {\n    if (!a.length)\n        return 0;\n    const s = [...a].sort((a, b) => a - b), x = Math.min(1, Math.max(0, q)) * (s.length - 1);\n    return s[Math.floor(x)] + (s[Math.ceil(x)] - s[Math.floor(x)]) * (x % 1);\n}\nfunction clamp(x, lo, hi) { return Math.max(lo, Math.min(hi, x)); }\nfunction formatTime(ms, precise = false) {","sourceCodeStart":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L607-L643","documentation":"errorOnsetOf() extracts the failure observation timestamp from a telemetry event's 'whalesong.error_onset_ms' attribute, falling back to startTime when absent. When the attribute is present it must be a finite number not earlier than the event's startTime; otherwise the observation time is inconsistent with the event itself and would produce a negative-duration signal view. The library throws to keep error onsets anchored to a valid timeline position.","triggerScenarios":"Processing a telemetry event whose attributes['whalesong.error_onset_ms'] is a non-number (string from JSON logs), NaN/Infinity, or a value smaller than e.startTime — e.g. an onset stamped with a different clock or recorded before the event began.","commonSituations":"Log exporters serializing the attribute as a string; clock skew between the component writing onset_ms and the one writing startTime; a producer using epoch ms while startTime uses a monotonic or relative clock; hand-crafted test events.","solutions":["Fix the producer to emit whalesong.error_onset_ms as a finite number on the same clock as startTime, with onset >= startTime.","If the attribute cannot be trusted, omit it entirely so errorOnsetOf falls back to e.startTime.","At the ingestion boundary, coerce/validate the attribute (parse strings, drop values < startTime) before the event reaches errorOnsetOf.","Synchronize clocks across the components that write startTime and error_onset_ms."],"exampleFix":"// before\ne.attributes['whalesong.error_onset_ms'] = String(Date.now()); // string, different clock\n// after\nconst onset = e.startTime + measuredDelayMs;\ne.attributes['whalesong.error_onset_ms'] = Math.max(onset, e.startTime); // number, same clock","handlingStrategy":"validation","validationCode":"function safeErrorOnset(e) {\n  const t = e.attributes?.['whalesong.error_onset_ms'];\n  if (t === undefined) return e.startTime;\n  const n = Number(t);\n  return (typeof n === 'number' && Number.isFinite(n) && n >= e.startTime) ? n : e.startTime;\n}","typeGuard":"const hasValidOnset = (e) => e.attributes?.['whalesong.error_onset_ms'] === undefined || (typeof e.attributes['whalesong.error_onset_ms'] === 'number' && Number.isFinite(e.attributes['whalesong.error_onset_ms']) && e.attributes['whalesong.error_onset_ms'] >= e.startTime);","tryCatchPattern":"try {\n  const onset = errorOnsetOf(e);\n} catch (err) {\n  if (err.message === 'Invalid failure observation time.') {\n    onset = e.startTime; // fall back to event start\n  } else throw err;\n}","preventionTips":["Emit error_onset_ms as a number on the same clock as startTime","Omit the attribute rather than writing an untrusted value","Validate/coerce telemetry attributes at ingestion","Keep clocks synchronized across components writing startTime and onset"],"tags":["telemetry","validation","timestamps"],"backgroundTag":"invalid-argument-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}