{"record":{"id":"9db540952f8284db","repo":"sigoden/aichat","slug":"blocked-due-to-safety","errorCode":null,"errorMessage":"Blocked due to safety","messagePattern":"Blocked due to safety","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/client/vertexai.rs","lineNumber":229,"sourceCode":"            if let Some(parts) = data[\"candidates\"][0][\"content\"][\"parts\"].as_array() {\n                for (i, part) in parts.iter().enumerate() {\n                    if let Some(text) = part[\"text\"].as_str() {\n                        if i > 0 {\n                            handler.text(\"\\n\\n\")?;\n                        }\n                        handler.text(text)?;\n                    } else if let (Some(name), Some(args)) = (\n                        part[\"functionCall\"][\"name\"].as_str(),\n                        part[\"functionCall\"][\"args\"].as_object(),\n                    ) {\n                        handler.tool_call(ToolCall::new(name.to_string(), json!(args), None))?;\n                    }\n                }\n            } else if let Some(\"SAFETY\") = data[\"promptFeedback\"][\"blockReason\"]\n                .as_str()\n                .or_else(|| data[\"candidates\"][0][\"finishReason\"].as_str())\n            {\n                bail!(\"Blocked due to safety\")\n            }\n\n            Ok(())\n        };\n        json_stream(res.bytes_stream(), handle).await?;\n    }\n    Ok(())\n}\n\nasync fn embeddings(builder: RequestBuilder, _model: &Model) -> Result<EmbeddingsOutput> {\n    let res = builder.send().await?;\n    let status = res.status();\n    let data: Value = res.json().await?;\n    if !status.is_success() {\n        catch_error(&data, status.as_u16())?;\n    }\n    let res_body: EmbeddingsResBody =\n        serde_json::from_value(data).context(\"Invalid embeddings data\")?;","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/client/vertexai.rs#L211-L247","documentation":"Safety sentinel from the Gemini streaming path: the candidate's parts array contains a safety-blocking part instead of text or a function call, meaning the provider's safety filters refused to generate content for the prompt. It is a guard branch while iterating response parts — the input at fault is the prompt (or conversation history) tripping content filters.","triggerScenarios":"Thrown at src/client/vertexai.rs:229 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rephrase the prompt to avoid the content that triggered the filter and retry","Enable/adjust safety settings on the request if the provider exposes them","If safety blocks recur, inform the user that the provider refused the request rather than retrying blindly","Trim or summarize conversation history that may be accumulating flagged content"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}