xai-org/grok-build · error · WebFetchError::IoError

session folder is unavailable

Error message

session folder is unavailable

What it means

require_media_session_folder unwraps an Option<&Path> for the media session folder, returning WebFetchError wrapping an io::ErrorKind::NotFound with message "session folder is unavailable" when it is None. fetch needs this folder to persist downloaded media; without it, media downloads cannot proceed.

Source

Thrown at crates/codegen/xai-grok-tools/src/implementations/grok_build/web_fetch/client.rs:456

            status_code,
        });
    }
}

/// Exact host equality — no `www.` stripping. Distinct DNS labels (even when
/// one is a `www` subdomain of the other) have independent A records and must
/// surface as cross-host redirects rather than auto-follow.
fn is_same_host(a: &Url, b: &Url) -> bool {
    a.host_str() == b.host_str()
}

// ───────────────────────────────────────────────────────────────────────────
// Content Processing
// ───────────────────────────────────────────────────────────────────────────

fn require_media_session_folder(session_folder: Option<&Path>) -> Result<&Path, WebFetchError> {
    session_folder.ok_or_else(|| {
        WebFetchError::IoError(std::io::Error::new(
            std::io::ErrorKind::NotFound,
            "session folder is unavailable",
        ))
    })
}

fn is_html(content_type: &str) -> bool {
    content_type.contains("text/html") || content_type.contains("application/xhtml")
}

fn is_pdf(content_type: &str) -> bool {
    content_type.contains("application/pdf")
}

/// Returns `true` for image content types, excluding SVG (which can contain
/// `<script>` tags and event handlers — an XSS vector if saved and opened).
fn is_image(content_type: &str) -> bool {
    let mime = content_type

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Create/allocate a session folder before calling fetch and pass it into the client.
  2. Check the client construction path to ensure session_folder is populated (builder/constructor wiring).
  3. If media download is optional, disable media fetching for this call instead of requiring the folder.
  4. Return a clearer, user-facing error at a higher layer explaining that a session must be started first.

Example fix

// before
let client = WebFetchClient::new(None);
let page = client.fetch(url).await?;
// after
let session_folder = ensure_session_folder("fetch-session")?;
let client = WebFetchClient::new(Some(&session_folder));
let page = client.fetch(url).await?;
Defensive patterns

Strategy: validation

Validate before calling

let session_folder = session_folder
    .ok_or_else(|| anyhow!("media fetch requires an initialized session folder"))?;
if !session_folder.is_dir() {
    std::fs::create_dir_all(&session_folder)?;
}

Type guard

fn has_session_folder(f: Option<&Path>) -> bool {
    f.map(|p| p.is_dir()).unwrap_or(false)
}

Try / catch

match client.fetch(url).await {
    Err(WebFetchError::IoError(e)) if e.kind() == std::io::ErrorKind::NotFound => {
        bail!("start a session (with a session folder) before media fetch")
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling WebFetchClient::fetch (a media-fetching path) on a client constructed without a session_folder — e.g. built via a constructor/test builder that leaves the folder unset, or a fetch invoked outside an active session context.

Common situations: Using the web fetch client in a REPL/tool context where no session directory was allocated; a regression where session setup was skipped or failed earlier and the None propagated; calling fetch for text-only pages but with media handling enabled.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/10440b47105ff331. Report an issue: GitHub.