Hmbown/CodeWhale · error · Error
Record requires nonempty id, traceId, and name.
Error message
Record ${index + 1} requires nonempty id, traceId, and name. What it means
normalizedEvent requires every ingested record to carry nonempty id, traceId, and name strings (via str(), which coerces and empties non-strings). If any is empty/missing, pet/src/core/ingest.ts:126 throws with the 1-based record index.
Solutions
- Populate id, traceId, and name with nonempty strings on every record
- Skip or repair records missing identity before calling the ingest API
- Check the mapping layer for fields renamed or dropped during conversion
Example fix
// before
{id:'', traceId:'t1', name:'db.query'}
// after
{id:'span-123', traceId:'t1', name:'db.query'} Defensive patterns
Strategy: validation
Validate before calling
if (!rec.id||!rec.traceId||!rec.name) throw new Error('record missing id/traceId/name before ingest'); Type guard
const hasIdentity=(r:any): r is {id:string;traceId:string;name:string} => typeof r?.id==='string'&&r.id.length>0&&typeof r?.traceId==='string'&&r.traceId.length>0&&typeof r?.name==='string'&&r.name.length>0; Try / catch
try { ingest(records); } catch (e) { if (/requires nonempty id, traceId, and name/.test(e.message)) { /* quarantine the bad record; the message names the index */ } else throw e; } Prevention
- Require id/traceId/name in your ingestion schema
- Sanitize upstream data that may contain null ids
- Generate ids at the producer if the source cannot supply them
When it happens
Trigger: Ingesting an OTLP trace where a span lacks spanId, traceId, or name — or those fields are non-strings (null/numbers) that coerce to ''.
Common situations: Spans exported from instrumentation that omits names on synthetic events; joins with null ids from upstream storage; partially written records from a crashing exporter.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Missing . Times must be numeric milliseconds.
- Automation transaction cannot replace its identity
- Bound task identity or schema does not match its durable…
- Duplicate event identity
- Duplicate policy identity.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/0ff27cfce1570e87.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/core/ingest.ts:126
return v;
}
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'),View on GitHub (pinned to 433685b202)