{"record":{"id":"10440b47105ff331","repo":"xai-org/grok-build","slug":"session-folder-is-unavailable","errorCode":null,"errorMessage":"session folder is unavailable","messagePattern":"session folder is unavailable","errorType":"exception","errorClass":"WebFetchError::IoError","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-tools/src/implementations/grok_build/web_fetch/client.rs","lineNumber":456,"sourceCode":"            status_code,\n        });\n    }\n}\n\n/// Exact host equality — no `www.` stripping. Distinct DNS labels (even when\n/// one is a `www` subdomain of the other) have independent A records and must\n/// surface as cross-host redirects rather than auto-follow.\nfn is_same_host(a: &Url, b: &Url) -> bool {\n    a.host_str() == b.host_str()\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Content Processing\n// ───────────────────────────────────────────────────────────────────────────\n\nfn require_media_session_folder(session_folder: Option<&Path>) -> Result<&Path, WebFetchError> {\n    session_folder.ok_or_else(|| {\n        WebFetchError::IoError(std::io::Error::new(\n            std::io::ErrorKind::NotFound,\n            \"session folder is unavailable\",\n        ))\n    })\n}\n\nfn is_html(content_type: &str) -> bool {\n    content_type.contains(\"text/html\") || content_type.contains(\"application/xhtml\")\n}\n\nfn is_pdf(content_type: &str) -> bool {\n    content_type.contains(\"application/pdf\")\n}\n\n/// Returns `true` for image content types, excluding SVG (which can contain\n/// `<script>` tags and event handlers — an XSS vector if saved and opened).\nfn is_image(content_type: &str) -> bool {\n    let mime = content_type","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-tools/src/implementations/grok_build/web_fetch/client.rs#L438-L474","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create/allocate a session folder before calling fetch and pass it into the client.","Check the client construction path to ensure session_folder is populated (builder/constructor wiring).","If media download is optional, disable media fetching for this call instead of requiring the folder.","Return a clearer, user-facing error at a higher layer explaining that a session must be started first."],"exampleFix":"// before\nlet client = WebFetchClient::new(None);\nlet page = client.fetch(url).await?;\n// after\nlet session_folder = ensure_session_folder(\"fetch-session\")?;\nlet client = WebFetchClient::new(Some(&session_folder));\nlet page = client.fetch(url).await?;","handlingStrategy":"validation","validationCode":"let session_folder = session_folder\n    .ok_or_else(|| anyhow!(\"media fetch requires an initialized session folder\"))?;\nif !session_folder.is_dir() {\n    std::fs::create_dir_all(&session_folder)?;\n}","typeGuard":"fn has_session_folder(f: Option<&Path>) -> bool {\n    f.map(|p| p.is_dir()).unwrap_or(false)\n}","tryCatchPattern":"match client.fetch(url).await {\n    Err(WebFetchError::IoError(e)) if e.kind() == std::io::ErrorKind::NotFound => {\n        bail!(\"start a session (with a session folder) before media fetch\")\n    }\n    other => other?,\n}","preventionTips":["Allocate the session folder during session setup, before any fetch calls.","Assert client invariants (session_folder set) in constructors/builders.","Skip or disable media handling when no session context exists.","Fail fast in tests when building a client without a folder if media fetch will be exercised."],"tags":["web-fetch","missing-config","not-found","session"],"backgroundTag":"missing-session-folder","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}