can1357/oh-my-pi · error · Error
unknown recall tier ${JSON.stringify(tier)}; valid tiers: ${
Error message
unknown recall tier ${JSON.stringify(tier)}; valid tiers: ${JSON.stringify(RECALL_TIERS)} What it means
RecallDiagnostics.recordTierHits accepts tier as a loose string but validates it against the known RECALL_TIERS set before recording; an unrecognized string throws a plain Error listing all valid tiers. This keeps tier statistics buckets consistent.
Source
Thrown at packages/mnemopi/src/core/recall-diagnostics.ts:63
private tierStats: Record<RecallTier, TierStats>;
private totalCalls: number;
private callsUsingWmFallback: number;
private callsUsingEmFallback: number;
private callsTrulyEmpty: number;
private createdAt: string;
constructor() {
this.tierStats = newTierStats();
this.totalCalls = 0;
this.callsUsingWmFallback = 0;
this.callsUsingEmFallback = 0;
this.callsTrulyEmpty = 0;
this.createdAt = new Date().toISOString();
}
private static validateTier(tier: string): asserts tier is RecallTier {
if (!isRecallTier(tier)) {
throw new Error(`unknown recall tier ${JSON.stringify(tier)}; valid tiers: ${JSON.stringify(RECALL_TIERS)}`);
}
}
recordTierHits(tier: RecallTier | string, hitCount: number): void {
RecallDiagnostics.validateTier(tier);
if (hitCount < 0) throw new Error(`hit_count must be >= 0, got ${hitCount}`);
const stats = this.tierStats[tier];
if (hitCount > 0) stats.callsWithHits++;
stats.totalHits += hitCount;
}
recordFallbackUsed(options: { readonly wm?: boolean; readonly em?: boolean } = {}): void {
if (options.wm === true) this.callsUsingWmFallback++;
if (options.em === true) this.callsUsingEmFallback++;
}
recordCall(options: { readonly trulyEmpty?: boolean; readonly truly_empty?: boolean } = {}): void {
this.totalCalls++;
if (options.trulyEmpty === true || options.truly_empty === true) this.callsTrulyEmpty++;
}View on GitHub (pinned to 9690622007)
Solutions
- Use the exported RecallTier constants instead of raw strings
- Inspect the error message's list of valid tiers and correct the tier value
- Validate/normalize the tier at the boundary (e.g. isRecallTier) before recording
Example fix
// before
diag.recordTierHits("vector", 2); // unknown tier
// after
import { isRecallTier } from "...";
const tier = "semantic"; // one of RECALL_TIERS
if (isRecallTier(tier)) diag.recordTierHits(tier, 2); Defensive patterns
Strategy: type-guard
Validate before calling
import { isRecallTier, RECALL_TIERS } from "...";
if (isRecallTier(tier)) diag.recordTierHits(tier, hits); Type guard
function isRecallTier(value: string): value is RecallTier {
return (RECALL_TIERS as readonly string[]).includes(value);
} Try / catch
try {
diag.recordTierHits(tier, hits);
} catch (err) {
if (err instanceof Error && err.message.startsWith("unknown recall tier")) {
logger.warn("dropping diagnostics for unknown tier", { tier });
return;
}
throw err;
} Prevention
- Use RecallTier constants instead of raw strings
- Validate tiers at system boundaries with isRecallTier
- Keep tier naming in sync when refactoring across systems
When it happens
Trigger: Calling recordTierHits("vector", 3) or any string outside RECALL_TIERS; passing a tier name from another system's taxonomy; passing a raw DB value that has drifted from the enum.
Common situations: Typo in a tier constant; refactoring renamed a tier in one place but not in callers logging diagnostics; interop with external pipelines emitting different tier labels.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- unknown extraction tier ${JSON.stringify(tier)}; valid tiers
- Unsupported language '{value}'. Supported: {}
- litterbox option ttl must be one of 1h, 12h, 24h, or 72h
- Invalid value: ${rawValue}. Valid values: ${valid.join(", ")
- Invalid --source: ${args.source}. Expected one of: ${TTSR_SO
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5b354a915ede2e5e.
Report an issue: GitHub.