{"record":{"id":"853240c068fccece","repo":"astrid-runtime/astrid","slug":"gateway-is-not-wired-to-a-live-audit-log-historic","errorCode":null,"errorMessage":"gateway is not wired to a live audit log; historical-query unavailable","messagePattern":"gateway is not wired to a live audit log; historical-query unavailable","errorType":"http","errorClass":"GatewayError::Internal","httpStatus":500,"severity":"error","filePath":"crates/astrid-gateway/src/routes/audit.rs","lineNumber":215,"sourceCode":"    )\n)]\npub async fn get_audit(\n    State(state): State<Arc<GatewayState>>,\n    Query(query): Query<AuditQuery>,\n    req: Request<axum::body::Body>,\n) -> GatewayResult<Json<AuditQueryResponse>> {\n    let caller = caller_from(&req)?;\n    let capability_probe = req\n        .extensions()\n        .get::<super::events::CapabilityProbe>()\n        .cloned()\n        .unwrap_or_else(super::events::CapabilityProbe::deny_all);\n    let caller_principal = caller.principal.clone();\n\n    let (audit_log, session_id) = match (state.audit_log.as_ref(), state.session_id.as_ref()) {\n        (Some(log), Some(sid)) => (log.clone(), sid.clone()),\n        _ => {\n            return Err(GatewayError::Internal(anyhow::anyhow!(\n                \"gateway is not wired to a live audit log; historical-query unavailable\"\n            )));\n        },\n    };\n\n    let limit = match query.limit {\n        Some(l) if l > MAX_LIMIT => {\n            return Err(GatewayError::BadRequest(format!(\n                \"limit {l} exceeds the cap of {MAX_LIMIT}\"\n            )));\n        },\n        Some(0) | None => DEFAULT_LIMIT,\n        Some(l) => l,\n    };\n\n    // Pull the full session slice from the audit log. The audit log\n    // doesn't expose an \"after cursor\" query primitive today, so we\n    // fetch + filter + paginate in-process. The persistent log on","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/audit.rs#L197-L233","documentation":"The historical audit-query endpoint returns this Internal (500) error when either state.audit_log or state.session_id is None. Both must be present because the handler reads entries for the caller's session from the audit log; a gateway started without an audit log (or without a session id) cannot serve historical queries.","triggerScenarios":"GET /api/audit (get_audit) on a gateway where audit_log or session_id in GatewayState is None — i.e. the server was built without a live audit log or session identity.","commonSituations":"Gateway launched in a mode that disables audit logging; audit backend failed to open at startup so audit_log stayed None; querying audit history on a freshly restarted node whose session_id hasn't been established.","solutions":["Start the gateway with a live audit log wired into GatewayState (audit_log: Some(...)).","Ensure session_id is set on GatewayState before serving traffic.","Fix any audit-backend initialization failure that left audit_log as None, then restart.","Don't expose the /api/audit route on deployments that intentionally run without an audit log."],"exampleFix":"// before\nlet state = GatewayState { audit_log: None, session_id: None, .. };\n// after\nlet audit = RotatingAuditLog::open(&config.audit_path).await?;\nlet state = GatewayState { audit_log: Some(Arc::new(audit)), session_id: Some(session_id), .. };","handlingStrategy":"fallback","validationCode":"// check audit capability before querying\nconst cap = await fetch('/api/audit/_capability');\nif (!cap.ok) return []; // historical query unsupported on this node","typeGuard":"fn audit_available(state: &GatewayState) -> bool {\n    state.audit_log.is_some() && state.session_id.is_some()\n}","tryCatchPattern":"try {\n  const entries = await fetch('/api/audit?limit=100');\n} catch (e) {\n  if (/historical-query unavailable/.test(e.message)) return []; // no audit backend on this node\n  throw e;\n}","preventionTips":["Run gateways with a configured audit log if audit history is needed.","Monitor startup logs for audit-log initialization failures and alert.","Return empty/degraded results rather than hard-failing UIs when audit is disabled."],"tags":["rust","gateway","audit","configuration"],"backgroundTag":"feature-not-enabled","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}