{"record":{"id":"796f8072d3f1e8bc","repo":"swc-project/swc","slug":"invaliddata-796f80","errorCode":"InvalidData","errorMessage":"expected newline","messagePattern":"expected newline","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/swc_sourcemap/src/decoder.rs","lineNumber":89,"sourceCode":"                            buf[..read].copy_from_slice(&local_buf[..read]);\n                            self.header_state = HeaderState::PastHeader;\n                            return Ok(read);\n                        }\n                    }\n                    HeaderState::Junk => {\n                        if byte == b'\\r' {\n                            HeaderState::AwaitingNewline\n                        } else if byte == b'\\n' {\n                            HeaderState::PastHeader\n                        } else {\n                            HeaderState::Junk\n                        }\n                    }\n                    HeaderState::AwaitingNewline => {\n                        if byte == b'\\n' {\n                            HeaderState::PastHeader\n                        } else {\n                            Err(io::Error::new(\n                                io::ErrorKind::InvalidData,\n                                \"expected newline\",\n                            ))?\n                        }\n                    }\n                    HeaderState::PastHeader => {\n                        let rem = read - offset;\n                        buf[..rem].copy_from_slice(&local_buf[offset..read]);\n                        return Ok(rem);\n                    }\n                };\n            }\n        }\n    }\n}\n\npub fn strip_junk_header(slice: &[u8]) -> io::Result<&[u8]> {\n    if slice.is_empty() || !is_junk_json(slice[0]) {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_sourcemap/src/decoder.rs#L71-L107","documentation":"swc_sourcemap transparently strips the XSSI-protection junk prefix that servers prepend to sourcemap JSON (e.g. `)]}'`). The streaming `StripHeaderReader` scans the leading bytes; after junk bytes it accepts an optional `\r` followed by a required `\n`. If a `\r` is seen and the next byte is NOT `\n` (crates/swc_sourcemap/src/decoder.rs:89), the file cannot be a valid junk-prefixed map, so the reader fails with `io::ErrorKind::InvalidData` ('expected newline').","triggerScenarios":"Decoding a sourcemap via a reader (SourceMap/SourceMapIndex from_reader paths) whose first byte is one of `) ] } '` and which contains a carriage return not immediately followed by a line feed inside the header region — e.g. `)]}\\rX{\"version\":3...}` or `)]}'` followed by a second stray CR before the JSON.","commonSituations":"Sourcemap files mangled by line-ending conversion (git autocrlf, FTP text mode, editor round-trips that turn the single header LF into CR or CRLFCR); custom XSSI guards emitting `)]}'` plus something other than a clean newline; concatenation scripts joining headers incorrectly.","solutions":["Rewrite the file so the junk header is exactly `)]}'` followed by one \\n and then the JSON","Remove the XSSI prefix entirely — the decoder also accepts files that start directly with the JSON","Fix the transfer/editor pipeline that rewrote line endings inside the header (git autocrlf, text-mode FTP)","If the leading bytes are legitimate content (file truly begins with `)`), re-encode the map so it starts with `{`"],"exampleFix":"// before (file bytes)\n)]}\\r)]}\\n{\"version\":3,...}\n// after\n)]}'\\n{\"version\":3,...}","handlingStrategy":"try-catch","validationCode":"// Check the header bytes before handing a reader to the sourcemap decoder\nfn header_is_clean(head: &[u8]) -> bool {\n    let junk: &[u8] = b\")]}'\";\n    if !head.starts_with(junk) && !matches!(head.first(), Some(b')' | b']' | b'}' | b'\\'')) { return true; }\n    // after junk bytes, allow at most one \\r immediately followed by \\n\n    let mut i = 0;\n    while i < head.len() && matches!(head[i], b')' | b']' | b'}' | b'\\'' ) { i += 1; }\n    if i < head.len() && head[i] == b'\\r' { i += 1; }\n    i < head.len() && head[i] == b'\\n'\n}","typeGuard":null,"tryCatchPattern":"match SourceMap::from_reader(StripHeaderReader::new(file)) {\n    Ok(sm) => sm,\n    Err(e) if e.to_string().contains(\"expected newline\") => {\n        // header is corrupt; strip the prefix manually and retry once from the '{' byte\n        retry_from_first_brace(file)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Serve sourcemaps with the exact `)]}'` + LF prefix, or with no prefix at all","Disable line-ending conversion for .map files (git attributes, editor settings)","Add a fixture test asserting the first bytes of every published .map file"],"tags":["sourcemap","xssi","io","line-endings","decoder"],"backgroundTag":"sourcemap-decode-failed","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}