{"record":{"id":"47f3e9296df4bea3","repo":"nikivdev/code","slug":"error-47f3e9","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/url_inspect.rs","lineNumber":795,"sourceCode":"        .or_else(|| std::env::var(\"SEQ_SCRAPER_API_KEY\").ok());\n    if let Some(token) = api_token {\n        request = request.bearer_auth(token);\n    }\n\n    let response = request\n        .send()\n        .context(\"failed to call configured scraper endpoint\")?;\n    let status = response.status();\n    let body = response\n        .text()\n        .context(\"failed to read scraper response body\")?;\n    if !status.is_success() {\n        bail!(\"http {}: {}\", status.as_u16(), body);\n    }\n    let payload: ScrapeResult =\n        serde_json::from_str(&body).context(\"failed to decode scraper response\")?;\n    if !payload.success {\n        bail!(\n            \"{}\",\n            payload\n                .error\n                .unwrap_or_else(|| \"scraper reported failure without an error\".to_string())\n        );\n    }\n\n    Ok(UrlInspectResult {\n        reference: url.to_string(),\n        provider: \"scraper\".to_string(),\n        final_url: payload.final_url,\n        status_code: payload.status_code,\n        content_type: payload.content_type,\n        title: payload.title,\n        description: None,\n        excerpt: payload\n            .text_excerpt\n            .map(|value| truncate_excerpt(&normalize_whitespace(&value))),","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/url_inspect.rs#L777-L813","documentation":"inspect_via_scraper calls an external scraping endpoint, gets HTTP 200, but the JSON ScrapeResult payload has success=false, so the scraper itself failed. The error surfaces the scraper's own error string, or a fallback message if it reported failure without one. This indicates the remote scraper service rejected or failed the job rather than a local HTTP/decoding problem.","triggerScenarios":"Calling inspect_url (scraper mode) when the endpoint returns 200 with a ScrapeResult JSON whose success field is false; also when success=false and payload.error is None, producing \"scraper reported failure without an error\".","commonSituations":"Target site blocks the scraper (CAPTCHA, 403 at the target), invalid or expired SEQ_SCRAPER_API_KEY / bearer token, scraper-side timeout on slow pages, unsupported URL scheme, or the scraper service returning a failure envelope for rate-limited jobs.","solutions":["Log or display payload.error from the scraper response to get the underlying cause before retrying.","Verify the scraper API key (SEQ_SCRAPER_API_KEY or the api_key passed in) is valid and not expired.","Retry the target URL; transient target-side blocks or slow responses often succeed on a second attempt.","Fall back to inspect_via_direct_fetch (direct mode) if the scraper cannot handle the URL.","If the message is the no-error fallback, check scraper service logs/health; the failure envelope is malformed."],"exampleFix":"// before: opaque handling\nlet result = inspect_url(url, opts)?;\n// after: catch and fall back to direct fetch\nmatch inspect_url(url, opts) {\n    Ok(result) => Ok(result),\n    Err(e) if e.to_string().contains(\"scraper\") => inspect_url_direct(url, opts),\n    Err(e) => Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match inspect_url(url, &opts) {\n    Ok(r) => r,\n    Err(e) => {\n        eprintln!(\"scraper failed: {e}\");\n        // fall back to direct fetch or surface payload.error to the user\n        inspect_url_direct(url, &opts).context(\"both scraper and direct fetch failed\")?\n    }\n}","preventionTips":["Keep SEQ_SCRAPER_API_KEY valid and rotate before expiry.","Pre-check target URLs for reachability before submitting to the scraper.","Always read payload.error rather than treating every failure as transient.","Have a direct-fetch fallback path in your caller code."],"tags":["rust","scraper","http","remote-service"],"backgroundTag":"scraper-job-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}