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
- Log or capture the raw response body to see what was actually returned (likely HTML from a proxy).
- Bypass or correctly configure the corporate proxy so api.github.com returns real JSON (Content-Type: application/json).
- Retry the request if the body was truncated by a transient network issue.
- 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
- Bypass TLS-intercepting proxies for api.github.com
- Verify Content-Type: application/json in your network
- Keep a bundled dist as fallback
- Log raw bodies when parsing fails
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Parsing failed due to: {s:?}
- No assets in release metadata
- No download URL for asset
- No download URL for checksum asset
- Depth limit reached. Likely a circular reference.
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/21b4614815b88e9e.
Report an issue: GitHub.