thedotmack/claude-mem · error
audit log insert failed
Error message
audit log insert failed
What it means
After mutating admin or queue actions, the route writes an audit record via repo.createAuditLog. The insert is best-effort: on rejection it logs this warning (with the action and requestId) and the user request still succeeds, but that action has no row in the audit log, which matters for compliance and traceability.
Source
Thrown at src/server/routes/v1/ServerV1PostgresRoutes.ts:1354
// details win on key conflict so explicit overrides still work.
const detailsWithRequestId: Record<string, unknown> = {
...(req.requestId ? { requestId: req.requestId } : {}),
...(details ?? {}),
};
const auditInput = {
teamId: req.authContext?.teamId ?? null,
projectId: projectId ?? req.authContext?.projectId ?? null,
actorId,
apiKeyId: req.authContext?.apiKeyId ?? null,
action,
resourceType: resolveAuditResourceType(action),
resourceId: targetId,
details: detailsWithRequestId,
};
try {
await repo.createAuditLog(auditInput);
} catch (error) {
logger.warn('SYSTEM', 'audit log insert failed', {
action,
requestId: req.requestId ?? null,
error: error instanceof Error ? error.message : String(error),
});
}
}
// Phase 11 — paginated job listing for team/project queue endpoints.
// Phase 12 — extended with `sourceType`, `since`, and (optional) payload
// selection. Filtering is enforced in SQL (WHERE team_id [, project_id,
// status, source_type, created_at]). Application-layer filtering is never
// trusted alone for tenant scope.
private async listJobsForScope(input: {
teamId: string;
projectId: string | null;
status: string | null;
sourceType?: string | null;
limit: number;View on GitHub (pinned to e2d1df569a)
Solutions
- Pull the warn line's action, requestId, and error fields: the error names the exact database failure
- Run pending migrations so audit_logs matches createAuditLog's columns
- If FK targets are the cause, confirm the actor and api-key rows exist (or that nullable handling matches the schema)
- For transient database blips, note the audit gap and re-issue the action if a complete trail is required
Example fix
// before
await repo.createAuditLog(auditInput);
// after: retry transient failures, give up loudly after N attempts
for (let attempt = 1; attempt <= 3; attempt++) {
try {
await repo.createAuditLog(auditInput);
break;
} catch (error) {
const transient = isPgDatabaseError(error)
&& ['57P01', '40001', '08000', '08006', '55P03'].includes(error.code);
if (!transient || attempt === 3) {
logger.warn('SYSTEM', 'audit log insert failed', { action, requestId, error: String(error) });
break;
}
await new Promise((resolve) => setTimeout(resolve, 100 * 2 ** attempt));
}
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-deploy check: the audit table must exist before audited routes ship
const { rows } = await pool.query("SELECT to_regclass('audit_logs') AS table_name");
if (!rows[0].table_name) throw new Error('audit_logs missing: run migrations first'); Type guard
function isPgDatabaseError(error: unknown): error is { code: string; detail?: string; message: string } {
return typeof error === 'object' && error !== null && 'code' in error
&& typeof (error as { code: unknown }).code === 'string';
} Try / catch
try {
await repo.createAuditLog(auditInput);
} catch (error) {
if (isPgDatabaseError(error) && ['08000', '08006', '40001', '55P03'].includes(error.code)) {
// transient: retry with backoff before accepting the audit gap
} else {
logger.warn('SYSTEM', 'audit log insert failed', { action, requestId, error: String(error) });
}
} Prevention
- Apply migrations before rolling out API versions that write new audit columns
- Alert on the 'audit log insert failed' log pattern so gaps are noticed, not silently accepted
- Keep audit inserts out of long transactions to avoid lock-cascade failures
- Track audit write failure rate as a compliance metric
When it happens
Trigger: Any audited v1 route call while the audit_logs insert fails: migrations not applied (missing table or columns), an FK violation for actorId or apiKeyId, a database connection blip, or schema drift between createAuditLog and the deployed table.
Common situations: Partial migrations during deploys; Postgres restart or failover mid-request; actor rows deleted between request and audit write; column type mismatches after an upgrade.
Related errors
- Cannot bootstrap server API key: CLAUDE_MEM_SERVER_DATABASE_
- Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL
- observation generation job status transition was not applied
- agent_event source_id must belong to project_id and team_id
- server_session_id must match the agent_event server_session_
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/929d1ad6838514ff.
Report an issue: GitHub.