{"record":{"id":"e320276b517f1e69","repo":"headroomlabs-ai/headroom","slug":"magika-session-lock-poisoned","errorCode":null,"errorMessage":"magika session lock poisoned","messagePattern":"magika session lock poisoned","errorType":"exception","errorClass":"MagikaDetectorError","httpStatus":null,"severity":"error","filePath":"crates/headroom-core/src/transforms/magika_detector.rs","lineNumber":324,"sourceCode":"#[derive(Debug, Error)]\npub enum MagikaDetectorError {\n    /// One-time session initialization failed (model load, ONNX init).\n    /// Once we hit this, every subsequent call also fails — there is no\n    /// retry path here. The router should surface and stop.\n    #[error(\"magika session init failed: {0}\")]\n    Init(String),\n\n    /// Inference call failed for this input. Usually transient; future\n    /// calls may succeed. The error message is the magika-side text;\n    /// we don't try to wrap it.\n    #[error(\"magika inference failed: {0}\")]\n    Inference(String),\n\n    /// Singleton lock was poisoned (a previous holder panicked while\n    /// holding it). The detector is unusable until the process\n    /// restarts. We don't auto-recover — a panicked detector means\n    /// something is corrupt and continuing would mask it.\n    #[error(\"magika session lock poisoned\")]\n    Poisoned,\n}\n\n/// One-process singleton holding the magika session. Lazily\n/// initialized on first call to [`magika_detect`].\n///\n/// `Mutex<Result<Session, ...>>` rather than `Result<Mutex<Session>>`\n/// so init failure is recorded once and replayed cheaply on every\n/// subsequent call (no re-attempting the load — if the model file is\n/// missing or ort can't init, retrying just wastes cycles).\nstatic MAGIKA_SESSION: OnceLock<Mutex<Result<Session, String>>> = OnceLock::new();\n\n/// Default cap on magika ONNX session init.\n///\n/// On some platforms `Session::new()` can hang indefinitely instead of\n/// returning an error. Root-caused on Windows: with `ort-load-dynamic`\n/// (Windows-gated in `Cargo.toml`), the bare `LoadLibrary(\"onnxruntime.dll\")`\n/// search resolves to `C:\\Windows\\System32\\onnxruntime.dll` — the Windows ML","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/crates/headroom-core/src/transforms/magika_detector.rs#L306-L342","documentation":"After content-decoding, the body bytes could not be decoded as UTF-8 (helpers.py:2515, in the bytes-less JSON body reader). This means the decoded payload is binary or in another charset — JSON request bodies must be UTF-8 per RFC 8259. The message hints at compression because an undecoded compressed body is the most common cause: a client compressed the payload but sent no (or an 'identity') Content-Encoding header.","triggerScenarios":"POSTing a gzip/zstd/brotli-compressed JSON body without a Content-Encoding header; sending JSON serialized as UTF-16 or Latin-1; binary garbage reaching the JSON route.","commonSituations":"Middleware that compresses bodies but strips headers; clients that pre-compress with no header; locale-sensitive serializers producing non-UTF-8 bytes.","solutions":["If the body is compressed, set the matching Content-Encoding header so the proxy decompresses it first","Serialize JSON with ensure_ascii and UTF-8: json.dumps(obj).encode('utf-8')","Send Content-Type: application/json; charset=utf-8 and verify the payload with a hex dump of the first bytes"],"exampleFix":"# before: compressed body, no header\nrequests.post(url, data=gzip.compress(json.dumps(payload).encode()))\n\n# after\nrequests.post(url, data=gzip.compress(json.dumps(payload).encode()), headers={\"Content-Encoding\": \"gzip\"})","handlingStrategy":"try-catch","validationCode":"raw.decode(\"utf-8\")  # client-side pre-flight; if this fails, fix encoding or header","typeGuard":null,"tryCatchPattern":"try:\n    payload = await _read_json_body(request)\nexcept ValueError as exc:\n    return JSONResponse({\"error\": {\"type\": \"invalid_request_error\", \"message\": str(exc)}}, status_code=400)","preventionTips":["Always send Content-Encoding when the body is compressed","Encode JSON with .encode('utf-8'), never platform-default charsets"],"tags":["encoding","utf-8","request-body","compression"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}