koala73/worldmonitor · error · Error
intelHistory.retract: no identifier resolved to a dedupeKey
Error message
intelHistory.retract: no identifier resolved to a dedupeKey — nothing was tombstoned. Unresolved ids: ${unresolvedIds.join(", ")}. A deleted or pruned row cannot be retracted by id; re-run with --dedupe-key to suppress the identity itself. What it means
Error "intelHistory.retract: no identifier resolved to a dedupeKey — nothing was tombstoned. Unresolved ids: ${unresolvedIds.join(", ")}. A deleted or pruned row cannot be retracted by id; re-run with --dedupe-key to suppress the identity itself." thrown in koala73/worldmonitor.
Source
Thrown at convex/intelHistory.ts:477
assertRetractionIdentifierBudget(args);
const reason = args.reason.trim();
if (!reason) {
throw new Error("intelHistory.retract: reason is required");
}
await touchAppendLock(ctx);
const { keys, unresolvedIds } = await resolveRetractionKeys(ctx, args);
// Fail loudly rather than report a successful no-op. A document id is the
// handle an operator copies out of a search result, and a row that was
// already pruned — or already retracted — no longer resolves to one. With
// no key to tombstone the loop below does nothing, and a 200 saying
// `deleted: 0, tombstoned: 0` reads as "already clean" when the truth is
// "nothing was suppressed and the next seed tick will re-add it". The
// recovery is in the message because the operator needs it right there.
if (keys.length === 0) {
throw new Error(
`intelHistory.retract: no identifier resolved to a dedupeKey — nothing was tombstoned. ` +
`Unresolved ids: ${unresolvedIds.join(", ")}. A deleted or pruned row cannot be ` +
`retracted by id; re-run with --dedupe-key to suppress the identity itself.`,
);
}
const retractedAt = Date.now();
let deleted = 0;
let tombstoned = 0;
let refreshed = 0;
for (const dedupeKey of keys) {
const [rows, existingTombstone] = await Promise.all([
// `collect` over the dedupe index rather than `first`: the index is
// meant to hold one row per key, and if an old bug ever put two there
// a retraction that removed only one would leave the poisoned text
// live while reporting success.
ctx.dbView on GitHub (pinned to eeab0a219f)
Solutions
- Re-run the retract with --dedupe-key to tombstone the identity itself when the row no longer resolves by document id
- If the row should still exist, verify the copied id — deleted or pruned rows cannot be retracted by id
- Treat the loud failure as intended: it prevents a silent no-op being mistaken for a successful retraction
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at convex/intelHistory.ts:477 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21).
Data as JSON: /api/errors/e58439d7e98dd504.
Report an issue: GitHub.