{"record":{"id":"b1b72ccd9f4be591","repo":"headroomlabs-ai/headroom","slug":"could-not-read-pipeline-config-file-0","errorCode":null,"errorMessage":"could not read pipeline config file: {0}","messagePattern":"could not read pipeline config file: (.+?)","errorType":"exception","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"crates/headroom-core/src/transforms/pipeline/config.rs","lineNumber":223,"sourceCode":"    pub min_segments: usize,\n    pub target_ratio: f64,\n}\n\n/// Knobs for the [`crate::transforms::pipeline::offloads::DiffNoise`]\n/// offload. Lockfile suffixes are matched against the new-file path\n/// at the end of each `diff --git` header.\n#[derive(Debug, Clone, Deserialize)]\npub struct DiffNoiseConfig {\n    pub min_lines: usize,\n    pub lockfile_suffixes: Vec<String>,\n    pub drop_whitespace_only_hunks: bool,\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum ConfigError {\n    #[error(\"invalid pipeline config TOML: {0}\")]\n    Parse(#[from] toml::de::Error),\n    #[error(\"could not read pipeline config file: {0}\")]\n    Io(std::io::Error),\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn from_default_str_does_not_panic() {\n        // Embedded TOML must always deserialize cleanly.\n        let _ = PipelineConfig::from_default_str();\n    }\n\n    #[test]\n    fn defaults_match_documented_thresholds() {\n        let cfg = PipelineConfig::default();\n        assert_eq!(cfg.pipeline.reformat_target_ratio, 0.5);\n        assert_eq!(cfg.pipeline.bloat_threshold, 0.5);","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/crates/headroom-core/src/transforms/pipeline/config.rs#L205-L241","documentation":"Same UTF-8 check as error 307, but raised in _read_json_body_with_bytes (helpers.py:2547) — the shared reader used by the Anthropic, OpenAI, and Bedrock handlers that also returns the post-decode bytes for passthrough decisions. The body bytes after content-decoding are not valid UTF-8, so JSON text decoding is impossible.","triggerScenarios":"Any proxied /v1/messages, OpenAI-compatible, or Bedrock-routed request whose (decompressed) bytes fail UTF-8 decoding: compressed body without a Content-Encoding header, or a non-UTF-8 charset payload.","commonSituations":"Compressed bodies with stripped headers on the main chat-completion paths; gateway re-encoding; clients on Windows producing UTF-16 JSON.","solutions":["Set the correct Content-Encoding header for compressed bodies","Encode JSON as UTF-8 before sending","Inspect the first bytes of the body: gzip is 1f 8b, zlib is 78 xx, zstd is 28 b5 2f fd — if you see these, the header was lost"],"exampleFix":"# before: zstd body, no header\nrequests.post(url, data=zstandard.compress(body))\n\n# after\nrequests.post(url, data=zstandard.compress(body), headers={\"Content-Encoding\": \"zstd\"})","handlingStrategy":"try-catch","validationCode":"raw.decode(\"utf-8\")  # verify before sending; check for magic bytes if compressed","typeGuard":null,"tryCatchPattern":"try:\n    result, raw = await _read_json_body_with_bytes(request)\nexcept ValueError as exc:\n    return JSONResponse({\"error\": {\"type\": \"invalid_request_error\", \"message\": str(exc)}}, status_code=400)","preventionTips":["Pair compression with the matching header in one helper on all main chat paths","Hex-dump the first bytes when debugging unexplained UTF-8 failures"],"tags":["encoding","utf-8","request-body","compression"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}