nikivdev/code · error

{}

Error message

{}

What it means

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.

Source

Thrown at src/url_inspect.rs:795

        .or_else(|| std::env::var("SEQ_SCRAPER_API_KEY").ok());
    if let Some(token) = api_token {
        request = request.bearer_auth(token);
    }

    let response = request
        .send()
        .context("failed to call configured scraper endpoint")?;
    let status = response.status();
    let body = response
        .text()
        .context("failed to read scraper response body")?;
    if !status.is_success() {
        bail!("http {}: {}", status.as_u16(), body);
    }
    let payload: ScrapeResult =
        serde_json::from_str(&body).context("failed to decode scraper response")?;
    if !payload.success {
        bail!(
            "{}",
            payload
                .error
                .unwrap_or_else(|| "scraper reported failure without an error".to_string())
        );
    }

    Ok(UrlInspectResult {
        reference: url.to_string(),
        provider: "scraper".to_string(),
        final_url: payload.final_url,
        status_code: payload.status_code,
        content_type: payload.content_type,
        title: payload.title,
        description: None,
        excerpt: payload
            .text_excerpt
            .map(|value| truncate_excerpt(&normalize_whitespace(&value))),

View on GitHub (pinned to a747e741ae)

Solutions

  1. Log or display payload.error from the scraper response to get the underlying cause before retrying.
  2. Verify the scraper API key (SEQ_SCRAPER_API_KEY or the api_key passed in) is valid and not expired.
  3. Retry the target URL; transient target-side blocks or slow responses often succeed on a second attempt.
  4. Fall back to inspect_via_direct_fetch (direct mode) if the scraper cannot handle the URL.
  5. If the message is the no-error fallback, check scraper service logs/health; the failure envelope is malformed.

Example fix

// before: opaque handling
let result = inspect_url(url, opts)?;
// after: catch and fall back to direct fetch
match inspect_url(url, opts) {
    Ok(result) => Ok(result),
    Err(e) if e.to_string().contains("scraper") => inspect_url_direct(url, opts),
    Err(e) => Err(e),
}
Defensive patterns

Strategy: try-catch

Try / catch

match inspect_url(url, &opts) {
    Ok(r) => r,
    Err(e) => {
        eprintln!("scraper failed: {e}");
        // fall back to direct fetch or surface payload.error to the user
        inspect_url_direct(url, &opts).context("both scraper and direct fetch failed")?
    }
}

Prevention

When it happens

Trigger: 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".

Common situations: 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.

Related errors


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