pbakaus/impeccable · error
TypeError: fetch failed: {}
Error message
TypeError: fetch failed: {}
What it means
The HTTP request from generate-image to the OpenAI image API failed at the transport level (ureq returned a non-status error). The command formats it as a Node-style "TypeError: fetch failed" and exits 1. This is a connectivity problem, not an HTTP error response from the API.
Source
Thrown at crates/context/src/generate_image.rs:357
m.insert("model".into(), Value::String("gpt-image-2".into()));
m.insert("prompt".into(), Value::String(prompt.clone()));
m.insert("size".into(), Value::String(size.clone()));
m.insert("quality".into(), Value::String(quality.clone()));
m.insert("n".into(), Value::from(1));
agent
.post("https://api.openai.com/v1/images/generations")
.set("Authorization", &format!("Bearer {}", key))
.set("content-type", "application/json")
.send_string(&serde_json::to_string(&Value::Object(m)).unwrap())
};
let (status, text) = match response {
Ok(r) => {
let st = r.status();
(st, r.into_string().unwrap_or_default())
}
Err(ureq::Error::Status(code, r)) => (code, r.into_string().unwrap_or_default()),
Err(e) => {
io.err(&format!("TypeError: fetch failed: {}\n", e));
return 1;
}
};
if !(200..300).contains(&status) {
let snippet: String = text.chars().take(300).collect();
io.err(&format!("generate-image: API error {}: {}\n", status, snippet));
return 1;
}
let json: Value = serde_json::from_str(&text).unwrap_or(Value::Null);
let b64 = json.get("data").and_then(|d| d.get(0)).and_then(|d| d.get("b64_json")).and_then(|b| b.as_str()).filter(|s| !s.is_empty());
let Some(b64) = b64 else {
io.err("generate-image: no image in response\n");
return 1;
};
let bytes = base64_decode(b64);
let _ = std::fs::write(abs(&out), bytes);
// best-effort embed + sidecar
// JS-PARITY: generate-image.mjs#676 reports whether the embed actuallyView on GitHub (pinned to 2bc2879276)
Solutions
- Check network connectivity: `curl -sS https://api.openai.com/v1/models -o /dev/null -w '%{http_code}'`.
- Verify proxy settings (HTTPS_PROXY/HTTP_PROXY) are correct if behind a corporate proxy, and that the CA bundle is available for TLS.
- Retry after confirming the network/VPN is up — transient DNS or connection failures resolve on their own.
- Inspect the printed underlying ureq error for the specific cause (DNS, connect, TLS) and fix accordingly.
- If in a container/sandbox, ensure outbound HTTPS egress to api.openai.com is allowed.
Example fix
// before impeccable generate-image --prompt "..." --out o.png // TypeError: fetch failed: dns error: ... // after export HTTPS_PROXY=http://proxy.corp:8080 impeccable generate-image --prompt "..." --out o.png # or run on a network with egress
Defensive patterns
Strategy: retry
Validate before calling
// preflight reachability
const ok = spawnSync("curl", ["-sS", "-o", "/dev/null", "-w", "%{http_code}", "https://api.openai.com/v1/models"]).status === 0;
if (!ok) console.warn("api.openai.com unreachable; generate-image will fail"); Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
const r = spawnSync("impeccable", ["generate-image", ...], { encoding: "utf8" });
if (r.status === 0) break;
if (r.stderr.includes("TypeError: fetch failed") && attempt < 3) {
await new Promise(res => setTimeout(res, 2 ** attempt * 1000));
continue;
}
throw new Error(r.stderr);
} Prevention
- Check VPN/proxy/firewall egress to api.openai.com before batch generation jobs.
- Set HTTPS_PROXY correctly in corporate environments.
- Retry transient network failures with exponential backoff.
- Keep system clocks synced to avoid TLS failures.
When it happens
Trigger: `ureq::Error` that is neither a status response nor a transport-success — DNS resolution failure, connection refused/timeout, TLS certificate error, proxy misconfiguration, or no network interface while POSTing to the images endpoint.
Common situations: Corporate proxy/firewall blocking api.openai.com; laptop offline or VPN down; DNS issues in containers; system clock skew causing TLS failures; IPv6-only environments that can't reach the endpoint.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Status failed: ${res.status} ${res.statusText}
- Poll failed: ${res.status} ${res.statusText}
- errBody.error || ('HTTP ' + res.status)
- HTTP ${res.status}
- ${String(res.status)}
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/d2ee07ca320f5d8c.
Report an issue: GitHub.