Hmbown/CodeWhale · error · Error
Record : unsupported schemaVersion .
Error message
Record ${index + 1}: unsupported schemaVersion ${a.schemaVersion}. What it means
normalizedEvent supports exactly schemaVersion 1. If a record carries a schemaVersion field with any other value, ingest rejects it (pet/src/core/ingest.ts:127) rather than guessing the shape — omitted schemaVersion is still accepted as v1.
Solutions
- Set schemaVersion to the number 1 or omit the field entirely
- Upgrade the ingest library to a version that supports the producer's schema
- Fix the producer to serialize schemaVersion as a number, not a string
Example fix
// before
{..., schemaVersion: '1'}
// after
{..., schemaVersion: 1} Defensive patterns
Strategy: validation
Validate before calling
if (rec.schemaVersion!==undefined && rec.schemaVersion!==1) throw new Error('unsupported schemaVersion'); Type guard
const isV1Record=(r:any): r is {schemaVersion?:1} & Record<string,unknown> => r?.schemaVersion===undefined||r?.schemaVersion===1; Try / catch
try { ingest(records); } catch (e) { if (/unsupported schemaVersion/.test(e.message)) { /* upgrade library or downgrade producer schema */ } else throw e; } Prevention
- Pin schemaVersion:1 in producer templates
- Add a compatibility check between producer and ingest library versions
- Serialize schemaVersion as a number, never a string
When it happens
Trigger: Ingesting records where a.schemaVersion is 2, '1' (string), or any value !== 1 after a producer upgrade.
Common situations: Producer upgraded to a newer schema before the ingest library did; schemaVersion serialized as a string instead of a number; copying a fixture from a different project with a different versioning scheme.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Bound task identity or schema does not match its durable…
- budget schema_version changed
- Duplicate event identity
- must be nonnegative.
- File exceeds the 64 MiB MVP import limit. Split the export…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/908e33f3bf01fc0d.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/core/ingest.ts:127
}
export function attributes(value: unknown): Obj {
if (!Array.isArray(value)) return obj(value);
return Object.fromEntries(value.filter(x => typeof x?.key === 'string').map(x => [x.key, decodeAnyValue(x.value)]));
}
function ns(v: unknown, field: string): bigint {
if (typeof v === 'number' && !Number.isSafeInteger(v)) throw new Error(`${field} lost precision: encode OTLP nanoseconds as a decimal string.`);
const s = String(v ?? '');
if (!/^\d{1,20}$/.test(s) || BigInt(s) > 18446744073709551615n) throw new Error(`Invalid ${field}: expected an OTLP nanosecond integer string.`);
return BigInt(s);
}
function otelStatus(v: unknown): Status {
const c = obj(v).code;
return c === 2 || c === 'STATUS_CODE_ERROR' ? 'error' : c === 1 || c === 'STATUS_CODE_OK' ? 'success' : 'unknown';
}
function normalizedEvent(v: unknown, index: number): WhaleEvent {
const a = obj(v), id = str(a.id), traceId = str(a.traceId), name = str(a.name);
if (!id || !traceId || !name) throw new Error(`Record ${index + 1} requires nonempty id, traceId, and name.`);
if (a.schemaVersion !== undefined && a.schemaVersion !== 1) throw new Error(`Record ${index + 1}: unsupported schemaVersion ${a.schemaVersion}.`);
const startTime = number(a.startTime, 'startTime', false)!;
const endTime = number(a.endTime, 'endTime') ?? startTime;
if (endTime < startTime) throw new Error(`Record ${index + 1}: endTime precedes startTime.`);
if (a.category !== undefined && !CATEGORIES.includes(a.category)) throw new Error(`Unknown category "${a.category}". Use "other" plus subtype for extensions.`);
const allowed: Status[] = ['pending', 'running', 'success', 'error', 'unknown'];
if (a.status !== undefined && !allowed.includes(a.status)) throw new Error(`Record ${index + 1}: invalid status.`);
const at = obj(a.attributes);
return {
schemaVersion: 1, id, traceId, name, parentId: str(a.parentId), startTime, endTime,
openEnded: a.endTime === undefined || a.openEnded === true,
agentId: str(a.agentId) ?? 'unattributed', agentType: str(a.agentType), parentAgentId: str(a.parentAgentId),
category: a.category ?? categoryFor(name, at), subtype: str(a.subtype),
model: str(a.model), provider: str(a.provider), tool: str(a.tool),
inputTokens: nonnegative(a.inputTokens, 'inputTokens'), outputTokens: nonnegative(a.outputTokens, 'outputTokens'),
cachedTokens: nonnegative(a.cachedTokens, 'cachedTokens'), cost: nonnegative(a.cost, 'cost'),
costCurrency: str(a.costCurrency), latency: nonnegative(a.latency, 'latency'),
contextTokens: nonnegative(a.contextTokens, 'contextTokens'), contextLimit: nonnegative(a.contextLimit, 'contextLimit'),
retry: nonnegative(a.retry, 'retry'), status: a.status ?? 'unknown',View on GitHub (pinned to 433685b202)