zed-industries/zed · error

missing Content-Type header

Error message

missing Content-Type header

What it means

After handling redirects and 4xx statuses, the fetch tool needs the Content-Type header to pick a parser: text/plain maps to plaintext, application/json to json, anything else to html (crates/agent/src/tools/fetch_tool.rs:119-130). A response with no Content-Type at all fails with 'missing Content-Type'. Note only client errors are checked earlier, so a 5xx or an empty 204 without the header also lands here.

Solutions

  1. Inspect the raw response with curl -I <url> to confirm the header is absent.
  2. If you control the server, set Content-Type on every response (application/json, text/html, text/plain).
  3. If not, download the resource yourself (curl -o file) and point the agent at the local file.
  4. Prefer endpoints that return proper headers (official docs and APIs) over hand-rolled ones.

Example fix

# before: endpoint sends no Content-Type
curl -I http://localhost:8000/data   # no content-type in response

# after: set it in the handler
Response::builder()
    .header("content-type", "application/json")
    .body(body)
Defensive patterns

Strategy: try-catch

Try / catch

let result = tool.run(input, cx).await;
match result {
    Ok(output) => { /* use content */ }
    Err(err) if err.to_string().contains("missing Content-Type") => {
        // fetch the resource out-of-band and reference a local copy
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: A server responds without a Content-Type header: bare or minimal HTTP servers, some redirects to endpoints that omit it, 204/no-content responses, misconfigured proxies stripping headers.

Common situations: Fetching from hand-rolled dev servers or internal endpoints that skip headers; empty-body responses; corporate proxies or gateways that drop headers.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/8d7a49f9961d41a8. Report an issue: GitHub.

Appendix: source

Thrown at crates/agent/src/tools/fetch_tool.rs:119

                "refusing to follow redirect to non-HTTP(S) URL {target}"
            );
            return Ok(FetchStep::Redirect(target.to_string()));
        }

        let mut body = Vec::new();
        response
            .body_mut()
            .read_to_end(&mut body)
            .await
            .context("error reading response body")?;

        if status.is_client_error() {
            let text = String::from_utf8_lossy(body.as_slice());
            bail!("status error {}, response: {text:?}", status.as_u16());
        }

        let Some(content_type) = response.headers().get("content-type") else {
            bail!("missing Content-Type header");
        };
        let content_type = content_type
            .to_str()
            .context("invalid Content-Type header")?;

        let content_type = if content_type.starts_with("text/plain") {
            ContentType::Plaintext
        } else if content_type.starts_with("application/json") {
            ContentType::Json
        } else {
            ContentType::Html
        };

        let text = match content_type {
            ContentType::Html => {
                let mut handlers: Vec<TagHandler> = vec![
                    Rc::new(RefCell::new(markdown::WebpageChromeRemover)),
                    Rc::new(RefCell::new(markdown::ParagraphHandler)),

View on GitHub (pinned to f4178619ac)