googleworkspace/cli · error · GwsError
5
5
Error message
Model Armor API returned status {status}: {resp_text} What it means
Returned by `sanitize_text()` when the Model Armor regional endpoint (`modelarmor.{location}.rep.googleapis.com/.../templates/{template}:sanitizeUserPrompt` or `:sanitizeModelResponse`) answers with a non-2xx HTTP status. The raw status code and response body are embedded verbatim, so the Google error JSON (e.g. `PERMISSION_DENIED`, `NOT_FOUND`, `INVALID_ARGUMENT`) is the actual diagnostic.
Source
Thrown at crates/google-workspace-cli/src/helpers/modelarmor.rs:274
let client = crate::client::build_client()?;
let resp = client
.post(&url)
.header("Authorization", format!("Bearer {token}"))
.header("Content-Type", "application/json")
.body(body)
.send()
.await
.context("Model Armor request failed")?;
let status = resp.status();
let resp_text = resp
.text()
.await
.context("Failed to read Model Armor response")?;
if !status.is_success() {
return Err(GwsError::Other(anyhow::anyhow!(
"Model Armor API returned status {status}: {resp_text}"
)));
}
parse_sanitize_response(&resp_text)
}
/// Make a POST request to Model Armor's regional API endpoint.
async fn model_armor_post(url: &str, body: &str) -> Result<(), GwsError> {
let token = auth::get_token(&[CLOUD_PLATFORM_SCOPE])
.await
.context("Failed to get auth token")?;
let client = crate::client::build_client()?;
let resp = client
.post(url)
.header("Authorization", format!("Bearer {token}"))
.header("Content-Type", "application/json")View on GitHub (pinned to a3768d0e82)
Solutions
- Read the embedded body: 404 NOT_FOUND means the template path is wrong — verify with `gws modelarmor projects locations templates list` (Discovery command).
- 403 PERMISSION_DENIED: enable the Model Armor API in the template's project and grant the caller `modelarmor.user` (or Editor) on it.
- Confirm the template string has all four segments: projects/PROJECT/locations/LOCATION/templates/TEMPLATE with a valid region like us-central1.
- 401/invalid token: re-run `gws auth login` or refresh ADC (`gcloud auth application-default login`).
Example fix
# before gws modelarmor +sanitize-prompt --template my-tmpl --text 'hello' # -> Model Armor API returned status 404 Not Found: ...NOT_FOUND... # after — full resource name with project + location gws modelarmor +sanitize-prompt \ --template projects/my-proj/locations/us-central1/templates/my-tmpl \ --text 'hello'
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the template resource name before calling sanitize_text
fn valid_template_name(t: &str) -> bool {
let parts: Vec<&str> = t.split('/').collect();
parts.len() == 6
&& parts[0] == "projects" && !parts[1].is_empty()
&& parts[2] == "locations" && !parts[3].is_empty()
&& parts[4] == "templates" && !parts[5].is_empty()
} Try / catch
match modelarmor::sanitize_text(&template, text).await {
Ok(res) => { /* inspect res.filter_match / res.sanitization_details */ }
Err(GwsError::Other(e)) => {
let msg = e.to_string();
if msg.contains("status 404") { eprintln!("template not found: {template}"); }
else if msg.contains("status 403") { eprintln!("enable modelarmor.googleapis.com and grant modelarmor.user"); }
else { return Err(e.into()); }
std::process::exit(1);
}
Err(e) => return Err(e),
} Prevention
- Store the fully-qualified template name (projects/P/locations/L/templates/T) in your pipeline config, never a bare id.
- Create templates with +create-template once in provisioning, verify with the Discovery get command, and reference that exact name.
- Keep the Model Armor API enabled and the caller's role granted in the template's project — 403 is almost always one of those two.
When it happens
Trigger: `gws modelarmor +sanitize-prompt --template projects/P/locations/L/templates/T ...` with a template that does not exist (404); the Model Armor API not enabled in project P (403); a typo'd location like `us-central` or `global` (404); a template name missing the `projects/.../templates/...` segments (400); an expired OAuth token (401).
Common situations: Sanitizing before sending via Gmail helpers with `--sanitize`; template created in one project/location but referenced with another; fresh GCP project where `modelarmor.googleapis.com` was never enabled; using a service account/ADC without the Model Armor User role.
Related errors
AI-assisted analysis of googleworkspace/cli@a3768d0e82 (2026-08-16).
Data as JSON: /api/errors/fc7a56f8bc2b451a.
Report an issue: GitHub.