{"record":{"id":"800d0011dadc30ea","repo":"zeroclaw-labs/zeroclaw","slug":"dall-e-failed-status-body-text","errorCode":null,"errorMessage":"DALL-E failed ({status}): {body_text}","messagePattern":"DALL-E failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/linkedin_client.rs","lineNumber":1090,"sourceCode":"            \"prompt\": prompt,\n            \"n\": 1,\n            \"size\": self.config.dalle.size,\n            \"response_format\": \"b64_json\"\n        });\n\n        let resp = client\n            .post(url)\n            .header(\"Authorization\", format!(\"Bearer {api_key}\"))\n            .header(\"Content-Type\", \"application/json\")\n            .json(&body)\n            .send()\n            .await\n            .context(\"DALL-E request failed\")?;\n\n        let status = resp.status();\n        if !status.is_success() {\n            let body_text = resp.text().await.unwrap_or_default();\n            anyhow::bail!(\"DALL-E failed ({status}): {body_text}\");\n        }\n\n        let json: serde_json::Value = resp.json().await?;\n        let b64 = json\n            .pointer(\"/data/0/b64_json\")\n            .and_then(|v| v.as_str())\n            .ok_or_else(|| {\n                ::zeroclaw_log::record!(\n                    ERROR,\n                    ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                        .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                        .with_attrs(::serde_json::json!({\"image_provider\": \"dalle\"})),\n                    \"linkedin_client: DALL-E response missing image data\"\n                );\n                anyhow::Error::msg(\"No image data in DALL-E response\")\n            })?;\n\n        let bytes = base64_decode(b64)?;","sourceCodeStart":1072,"sourceCodeEnd":1108,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/linkedin_client.rs#L1072-L1108","documentation":"try_dalle posts to OpenAI's image generation endpoint and bails on any non-2xx status with the body embedded. The OpenAI key was already found in .env, so this error reflects the API response: invalid credentials, billing/quota limits, parameter rejection, or content policy.","triggerScenarios":"401 for an invalid or revoked OPENAI_API_KEY; 429 when the org hits rate limits or has no billing; 400 for an invalid size/quality/model combination or malformed prompt; 400 with content_policy_violation for disallowed prompts.","commonSituations":"Key rotated in the OpenAI dashboard but not in workspace .env; trial credits exhausted; requesting dall-e-2 sizes on a dall-e-3 config (or vice versa); prompts that mention public figures.","solutions":["Read the embedded body_text; OpenAI's message distinguishes auth, billing, invalid_request_error, and content policy","Update the key in the env var named by the dalle api_key_env config if 401","Check org billing and rate limits on 429, then back off","Fix the size/model parameters per the current OpenAI images API, and configure a second provider for fallthrough"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"Per-provider failure consumed by generate(); on terminal failure, read the WARN log entry carrying the DALL-E status/body: 401 means fix the key, 429 means billing/quota, content_policy means rephrase.","preventionTips":["Keep OpenAI billing active and quota headroom for image bursts","Use size/quality values valid for the configured model generation","Keep another provider configured for fallthrough"],"tags":["openai","dalle","image-generation","http","api-key"],"backgroundTag":"image-generation-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}