{"record":{"id":"78897017564cbf38","repo":"thedotmack/claude-mem","slug":"failed-to-write-operator-audit-row","errorCode":null,"errorMessage":"failed to write operator audit row","messagePattern":"failed to write operator audit row","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/npx-cli/commands/server-jobs.ts","lineNumber":430,"sourceCode":"\ninterface PoolLike {\n  query: (sql: string, params: unknown[]) => Promise<{ rows: unknown[] }>;\n}\n\nasync function writeOperatorAudit(\n  pool: { query: (sql: string, params: unknown[]) => Promise<unknown> },\n  job: JobLookup,\n  action: string,\n  details: Record<string, unknown>,\n): Promise<void> {\n  try {\n    await pool.query(\n      `INSERT INTO audit_log (id, team_id, project_id, actor_id, api_key_id, action, resource_type, resource_id, details)\n       VALUES (gen_random_uuid(), $1, $2, NULL, NULL, $3, 'observation_generation_job', $4, $5::jsonb)`,\n      [job.team_id, job.project_id, action, job.id, JSON.stringify({ ...details, source: 'cli_operator' })],\n    );\n  } catch (error) {\n    logger.warn('SYSTEM', 'failed to write operator audit row', {\n      action,\n      jobId: job.id,\n      error: error instanceof Error ? error.message : String(error),\n    });\n  }\n}\n\nfunction extractRetriedCount(payload: Record<string, unknown> | null | undefined): number {\n  if (!payload || typeof payload !== 'object') return 0;\n  const value = (payload as { retried_count?: unknown }).retried_count;\n  return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? Math.floor(value) : 0;\n}\n\nfunction detectDivergence(\n  pg: Record<string, number>,\n  bullmq: Record<string, { waiting: number; active: number; completed: number; failed: number; delayed: number; stalled: number }> | null,\n): Record<string, unknown> {\n  if (!bullmq) return { reason: 'bullmq_unavailable' };","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/npx-cli/commands/server-jobs.ts#L412-L448","documentation":"writeOperatorAudit inserts an audit_log row (via Postgres) recording CLI operator actions (retry/cancel) on observation-generation jobs. If the INSERT fails, it logs this warning and swallows the error — the operator action itself is not rolled back, only the audit trail entry is lost.","triggerScenarios":"Running `jobs retry` or `jobs cancel` when the audit INSERT into audit_log fails — Postgres down, table missing, gen_random_uuid() unavailable (old PG without pgcrypto), FK violation on team_id/project_id/actor columns, or permission denied on audit_log.","commonSituations":"Database migration not applied (audit_log table absent); PostgreSQL < 13 without pgcrypto enabled; restricted DB role lacking INSERT on audit_log; transient connection loss.","solutions":["Check the logged `error` detail in the warn payload to identify the root SQL cause.","Apply pending migrations so the audit_log table and its columns exist.","Ensure the DB role has INSERT permission on audit_log and pgcrypto/gen_random_uuid() is available.","Verify Postgres connectivity, then re-run the operator action if the audit row matters."],"exampleFix":"// before: gen_random_uuid() undefined\nCREATE EXTENSION IF NOT EXISTS pgcrypto;\n// or on PG13+\n-- nothing needed; verify table exists\n\\d audit_log\n// after: retry the action\nclaude-mem server jobs retry <jobId>","handlingStrategy":"validation","validationCode":"-- Before running operator actions, verify prerequisites\nSELECT to_regclass('audit_log');            -- table exists?\nSELECT gen_random_uuid();                   -- pgcrypto/PG13+ available?\nSELECT has_table_privilege(current_user, 'audit_log', 'INSERT');","typeGuard":"function isAuditInsertError(e: unknown): boolean {\n  const msg = e instanceof Error ? e.message : String(e);\n  return /audit_log|permission denied|gen_random_uuid|relation .* does not exist/i.test(msg);\n}","tryCatchPattern":"try {\n  await pool.query(insertAuditSql, params);\n} catch (error) {\n  logger.warn('SYSTEM', 'failed to write operator audit row', {\n    action,\n    jobId: job.id,\n    error: error instanceof Error ? error.message : String(error),\n  }); // deliberate swallow: audit loss must not fail the operator action\n}","preventionTips":["Apply all DB migrations before using jobs commands","Grant INSERT on audit_log to the CLI/server DB role","Enable pgcrypto or use PG13+ for gen_random_uuid()","Monitor Postgres connectivity in CI/operator environments"],"tags":["postgres","audit","database","jobs"],"backgroundTag":"database-write-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}