{"record":{"id":"6fcc991d5a5ea25f","repo":"BoundaryML/baml","slug":"no-download-url-for-asset","errorCode":null,"errorMessage":"No download URL for asset","messagePattern":"No download URL for asset","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/playground-server/src/server.rs","lineNumber":168,"sourceCode":"    }\n\n    tracing::info!(\"Parsing JSON response...\");\n    let release: serde_json::Value = resp\n        .json()\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse JSON response: {e}\"))?;\n\n    // Find the main asset\n    let assets = release[\"assets\"]\n        .as_array()\n        .ok_or_else(|| anyhow::anyhow!(\"No assets in release metadata\"))?;\n    let asset = assets\n        .iter()\n        .find(|a| a[\"name\"].as_str() == Some(&web_panel_asset_name))\n        .ok_or_else(|| anyhow::anyhow!(\"No asset named '{}' in release\", web_panel_asset_name))?;\n    let download_url = asset[\"browser_download_url\"]\n        .as_str()\n        .ok_or_else(|| anyhow::anyhow!(\"No download URL for asset\"))?;\n\n    // Find the checksum asset\n    let checksum_asset = assets\n        .iter()\n        .find(|a| a[\"name\"].as_str() == Some(&checksum_asset_name))\n        .ok_or_else(|| {\n            anyhow::anyhow!(\n                \"No checksum asset named '{}' in release\",\n                checksum_asset_name\n            )\n        })?;\n    let checksum_url = checksum_asset[\"browser_download_url\"]\n        .as_str()\n        .ok_or_else(|| anyhow::anyhow!(\"No download URL for checksum asset\"))?;\n\n    tracing::info!(\n        \"Found assets - main: {}, checksum: {}\",\n        download_url,","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/playground-server/src/server.rs#L150-L186","documentation":"After finding the matching asset, get_playground_dist reads asset[\"browser_download_url\"].as_str(). If the asset object lacks that field (or it isn't a string), this error is returned. A GitHub release asset should always carry browser_download_url, so this indicates a malformed or unexpected asset object.","triggerScenarios":"The matched asset JSON has no string browser_download_url field — e.g. hand-crafted/mock release metadata, or an unexpected API payload shape.","commonSituations":"Testing against mocked GitHub API responses missing fields; a GitHub API payload change; proxy-injected JSON that drops fields.","solutions":["Inspect the asset JSON and confirm browser_download_url is present; fix the mocked/intermediary payload if it is synthetic.","Use the html_url/upload URL to reconstruct the download URL as a fallback if the field is genuinely absent.","Update parsing code if the GitHub API schema changed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// preflight: confirm asset objects carry browser_download_url\nlet v: serde_json::Value = reqwest::get(&api_url).await?.json().await?;\nlet ok = v[\"assets\"].as_array().map_or(false, |a| {\n    a.iter().all(|x| x[\"browser_download_url\"].is_string())\n});\nif !ok { eprintln!(\"Release payload missing browser_download_url fields\"); }","typeGuard":"fn download_url<'a>(asset: &'a serde_json::Value) -> Option<&'a str> {\n    asset[\"browser_download_url\"].as_str()\n}","tryCatchPattern":"match get_playground_dist().await {\n    Err(e) if e.to_string().contains(\"No download URL for asset\") => {\n        eprintln!(\"Malformed asset payload — inspect the GitHub API response\");\n    }\n    other => other?,\n}","preventionTips":["Use real GitHub API responses (not hand-made mocks missing fields)","Validate asset JSON shape in tests","Reconstruct URLs from asset IDs as fallback"],"tags":["github-api","json","unexpected-response","rust"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}