{"record":{"id":"d4ad12d1779ddb4c","repo":"koala73/worldmonitor","slug":"account-owner-fence-conflict","errorCode":"ACCOUNT_OWNER_FENCE_CONFLICT","errorMessage":"ACCOUNT_OWNER_FENCE_CONFLICT","messagePattern":"ACCOUNT_OWNER_FENCE_CONFLICT","errorType":"error_code","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/companyMonitoring/accounts.ts","lineNumber":122,"sourceCode":"    Math.max(0, delayMs),\n    internal.companyMonitoring.accounts.advanceAccountPurge,\n    { ownerFenceHash, purgeGeneration },\n  );\n}\n\nasync function findAccountByOwnerFence(\n  ctx: MutationCtx,\n  ownerFence: CompanyMonitoringOwnerFenceCandidates,\n): Promise<{ account: Doc<\"companyMonitoringAccounts\">; matchedHash: string } | null> {\n  let match: { account: Doc<\"companyMonitoringAccounts\">; matchedHash: string } | null = null;\n  for (const ownerFenceHash of ownerFence.all) {\n    const account = await ctx.db\n      .query(\"companyMonitoringAccounts\")\n      .withIndex(\"by_ownerFenceHash\", (q) => q.eq(\"ownerFenceHash\", ownerFenceHash))\n      .unique();\n    if (!account) continue;\n    if (match && match.account._id !== account._id) {\n      throw new ConvexError(\"ACCOUNT_OWNER_FENCE_CONFLICT\");\n    }\n    match = { account, matchedHash: ownerFenceHash };\n  }\n  return match;\n}\n\nasync function findAccountByOwnerUserId(\n  ctx: MutationCtx,\n  ownerUserId: string,\n): Promise<Doc<\"companyMonitoringAccounts\"> | null> {\n  const accounts = await ctx.db\n    .query(\"companyMonitoringAccounts\")\n    .withIndex(\"by_ownerUserId\", (q) => q.eq(\"ownerUserId\", ownerUserId))\n    .take(2);\n  if (accounts.length > 1) throw new ConvexError(\"ACCOUNT_OWNER_FENCE_CONFLICT\");\n  return accounts[0] ?? null;\n}\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/convex/companyMonitoring/accounts.ts#L104-L140","documentation":"Account-lookup fence conflict raised via findAccountByOwnerFence: the owner-fence hash candidate resolution produced a conflicting or ambiguous match among companyMonitoringAccounts rows. The owner fence hash binds an account to exactly one owner identity, so a conflict means the account-to-owner mapping is inconsistent — a fence-hash collision or a stale duplicate account.","triggerScenarios":"Thrown at convex/companyMonitoring/accounts.ts:122 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect all companyMonitoringAccounts rows matching the ownerFenceHash candidates for duplicates or stale rows","If a stale duplicate exists, let the purge/reaper flow terminalize it rather than manually patching fences","Verify the owner-fence hash computation inputs (owner identity fields) have not changed format"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}