nikivdev/code · error

failed to decode json line: {err}

Error message

failed to decode json line: {err}

What it means

parse_json_line's fallback path uses serde_json::from_str when the simd-json feature/target combination is not active. On decode failure it wraps the serde_json error as "failed to decode json line: {err}". Same contract as the simd path, different backend.

Source

Thrown at src/json_parse.rs:23

pub fn parse_json_line<T: DeserializeOwned>(line: &str) -> Result<T> {
    #[cfg(all(
        feature = "linux-host-simd-json",
        target_os = "linux",
        any(target_arch = "x86_64", target_arch = "aarch64")
    ))]
    {
        let mut buf = line.as_bytes().to_vec();
        return simd_json::serde::from_slice(&mut buf)
            .map_err(|err| anyhow!("failed to decode json line with simd-json: {err}"));
    }

    #[cfg(not(all(
        feature = "linux-host-simd-json",
        target_os = "linux",
        any(target_arch = "x86_64", target_arch = "aarch64")
    )))]
    {
        serde_json::from_str(line).map_err(|err| anyhow!("failed to decode json line: {err}"))
    }
}

#[inline]
pub fn parse_json_bytes_in_place<T: DeserializeOwned>(bytes: &mut [u8]) -> Result<T> {
    #[cfg(all(
        feature = "linux-host-simd-json",
        target_os = "linux",
        any(target_arch = "x86_64", target_arch = "aarch64")
    ))]
    {
        return simd_json::serde::from_slice(bytes)
            .map_err(|err| anyhow!("failed to decode json bytes with simd-json: {err}"));
    }

    #[cfg(not(all(
        feature = "linux-host-simd-json",
        target_os = "linux",

View on GitHub (pinned to a747e741ae)

Solutions

  1. Inspect the wrapped serde_json error for position and reason
  2. Ensure lines are complete JSON before parsing (line buffering)
  3. Skip or quarantine non-JSON lines instead of failing the whole stream
  4. Verify the consumer struct matches the producer's JSON schema

Example fix

// before
lines.map(|l| parse_json_line::<Event>(&l)).collect::<Result<Vec<_>>>()?
// after
let events = lines.filter_map(|l| {
    let l = l.trim();
    (!l.is_empty() && l.starts_with('{')).then_some(l)
}).map(|l| parse_json_line::<Event>(l)).collect::<Result<Vec<_>>>()?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn is_complete_json_line(line: &str) -> bool {
    let t = line.trim();
    !t.is_empty() && serde_json::from_str::<serde_json::Value>(t).is_ok()
}

Try / catch

match parse_json_line::<Event>(line) {
    Ok(v) => handle(v),
    Err(e) => {
        eprintln!("bad json line: {e:#}; line={line:.200}");
        // quarantine and continue
    }
}

Prevention

When it happens

Trigger: A malformed or truncated JSON line is passed to parse_json_line on non-Linux, non-x86_64/aarch64 targets, or builds without the linux-host-simd-json feature.

Common situations: Log lines split across flushes; producer emits non-JSON output (warnings, banners) interleaved with JSON lines; consumer struct out of sync with producer schema.

Understand the failure class

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/cc280985663b1cf5. Report an issue: GitHub.