Hmbown/CodeWhale · error · Error
Unknown privacy mode.
Error message
Unknown privacy mode.
What it means
importTrace validates the options.privacy mode against the closed set ['redact', 'metadata', 'retain']. An unrecognized privacy mode string makes the import ambiguous about how sensitive attribute values are treated, so it is rejected.
Solutions
- Use one of the exact literals: 'redact', 'metadata', or 'retain'.
- Normalize/validate the incoming option (lowercase, whitelist check) before calling importTrace.
- Omit options.privacy entirely to get the default 'redact' behavior.
Example fix
// before
importTrace(text, 't.json', { privacy: 'Redact' });
// after
importTrace(text, 't.json', { privacy: 'redact' }); Defensive patterns
Strategy: validation
Validate before calling
const PRIVACY_MODES = ['redact', 'metadata', 'retain'];
const mode = options.privacy ?? 'redact';
if (!PRIVACY_MODES.includes(mode)) throw new Error(`privacy must be one of ${PRIVACY_MODES.join(', ')}`); Type guard
type PrivacyMode = 'redact' | 'metadata' | 'retain'; const isPrivacyMode = (m: unknown): m is PrivacyMode => m === 'redact' || m === 'metadata' || m === 'retain';
Try / catch
try {
traces = importTrace(text, file, { privacy });
} catch (e) {
if (e instanceof Error && e.message === 'Unknown privacy mode.') {
console.error(`Invalid privacy '${privacy}', using default 'redact'`);
traces = importTrace(text, file, { privacy: 'redact' });
} else throw e;
} Prevention
- Use a typed enum/union for the privacy option instead of raw strings.
- Validate CLI/env-supplied modes against the whitelist before calling.
- Rely on the default 'redact' when unsure.
When it happens
Trigger: Calling importTrace(text, name, { privacy: 'redacted' }) or any value other than exactly 'redact', 'metadata', or 'retain' (wrong casing, synonyms like 'full'/'none', typos).
Common situations: Passing user-supplied CLI/config strings straight through; casing mistakes ('Redact'); API drift after a mode was renamed in a newer version; UI dropdowns not synced with the allowed values.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid approval_policy
- Invalid auto_review.
- Invalid verbosity ' ': expected normal or concise.
- maxEvents must be in [1, 250000].
- a CNB access token is not configured in the Codewhale…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/9fdeaa8a9a0733fa.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/core/ingest.ts:220
raw: rec,
};
events.push(e);
for (const [i, record] of list(s.events).entries()) {
const ea = attributes(record.attributes), time = Number(ns(record.timeUnixNano, 'event.timeUnixNano') - origin) / 1e6;
const ename = String(record.name ?? 'span event');
events.push({ schemaVersion: 1, id: `${s.spanId}/event/${i}`, traceId: s.traceId, parentId: s.spanId,
startTime: time, endTime: time, agentId: e.agentId, name: ename, category: categoryFor(ename, ea),
status: ename === 'exception' ? 'error' : 'unknown', attributes: ea, raw: { event: record, spanId: s.spanId, resource: rec.resource, scope: rec.scope } });
}
if (events.length > maxEvents) throw new Error(`Import exceeds the ${maxEvents.toLocaleString()} event limit, including span events.`);
}
return { events, origins: new Map([...bases].map(([k, v]) => [k, v.toString()])), warnings };
}
/** Parse strictly: malformed lines or duplicate identities never disappear silently. */
export function importTrace(text: string, filename = 'Imported trace', options: ImportOptions = {}): Trace[] {
const mode = options.privacy ?? 'redact', maxEvents = options.maxEvents ?? 250_000;
if (!['redact', 'metadata', 'retain'].includes(mode)) throw new Error('Unknown privacy mode.');
const maxTraces = options.maxTraces ?? 8;
if (!Number.isInteger(maxEvents) || maxEvents < 1 || maxEvents > 250_000) throw new Error('maxEvents must be in [1, 250000].');
if (!Number.isInteger(maxTraces) || maxTraces < 1 || maxTraces > 64) throw new Error('maxTraces must be in [1, 64].');
if (new TextEncoder().encode(text).length > (options.maxBytes ?? 64 * 1024 * 1024)) throw new Error('File exceeds the 64 MiB MVP import limit. Split the export by trace.');
const trimmed = text.replace(/^\uFEFF/, '').trim();
if (!trimmed) throw new Error('The trace file is empty.');
let document: unknown;
try { document = JSON.parse(trimmed); }
catch {
document = trimmed.split(/\r?\n/).filter(l => l.trim()).map((line, i) => {
try { return JSON.parse(line); } catch { throw new Error(`Invalid JSON on nonempty line ${i + 1}. Import cancelled; no rows were skipped.`); }
});
}
// Transform before both normalization and raw retention, so raw cannot bypass redaction.
const safe = mode === 'retain' ? (options.redactor ? options.redactor(document, '') : document) : redact(document, '', options.redactor);
const root = obj(safe);
if(root.format === 'whalesong.evidence/v1') return [evidenceToTrace(validateBundle(root, Math.min(maxEvents, 100_000)))];
if (isCodewhaleSession(safe)) {View on GitHub (pinned to 433685b202)