BoundaryML/baml · error

Failed to parse JSON response: {e}

Error message

Failed to parse JSON response: {e}

What it means

Once a successful response is received, get_playground_dist deserializes the body into serde_json::Value via resp.json(). If the body is not valid JSON (or the content is malformed/HTML), the reqwest/serde error is wrapped with this message. GitHub is expected to return JSON, so this indicates the body was not the expected release payload.

Source

Thrown at engine/playground-server/src/server.rs:156

    // Check if the response is successful
    if !resp.status().is_success() {
        let status = resp.status();
        let body = resp
            .text()
            .await
            .unwrap_or_else(|_| "Failed to read response body".to_string());
        return Err(anyhow::anyhow!(
            "GitHub API request failed with status {}: {}",
            status,
            body
        ));
    }

    tracing::info!("Parsing JSON response...");
    let release: serde_json::Value = resp
        .json()
        .await
        .map_err(|e| anyhow::anyhow!("Failed to parse JSON response: {e}"))?;

    // Find the main asset
    let assets = release["assets"]
        .as_array()
        .ok_or_else(|| anyhow::anyhow!("No assets in release metadata"))?;
    let asset = assets
        .iter()
        .find(|a| a["name"].as_str() == Some(&web_panel_asset_name))
        .ok_or_else(|| anyhow::anyhow!("No asset named '{}' in release", web_panel_asset_name))?;
    let download_url = asset["browser_download_url"]
        .as_str()
        .ok_or_else(|| anyhow::anyhow!("No download URL for asset"))?;

    // Find the checksum asset
    let checksum_asset = assets
        .iter()
        .find(|a| a["name"].as_str() == Some(&checksum_asset_name))
        .ok_or_else(|| {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Log or capture the raw response body to see what was actually returned (likely HTML from a proxy).
  2. Bypass or correctly configure the corporate proxy so api.github.com returns real JSON (Content-Type: application/json).
  3. Retry the request if the body was truncated by a transient network issue.
  4. Verify the API URL hasn't been redirected to an unexpected host.
Defensive patterns

Strategy: try-catch

Try / catch

// treat non-JSON bodies (proxy pages) as network-layer failure
match get_playground_dist().await {
    Err(e) if e.to_string().contains("Failed to parse JSON response") => {
        eprintln!("Non-JSON body — check proxy/interception");
        fallback_to_bundled_dist();
    }
    other => other?,
}

Prevention

When it happens

Trigger: resp.json::<serde_json::Value>() fails because the response body is not parseable JSON — e.g. a proxy or captive portal returned an HTML error page with a 2xx status, or the body was truncated.

Common situations: Corporate proxy/interception appliance returning HTML with 200 OK; a caching layer serving a corrupt or empty body; misrouted request hitting a non-GitHub endpoint after config changes.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/21b4614815b88e9e. Report an issue: GitHub.