zeroclaw-labs/zeroclaw · error

google_workspace.allowed_operations[{i}].resource must not b

Error message

google_workspace.allowed_operations[{i}].resource must not be empty

What it means

Config::validate() rejects any [[google_workspace.allowed_operations]] entry whose `resource` field is empty or whitespace-only. The resource segment (e.g. `calendarList`, `files`) is a required part of the service.resource[.sub_resource] tool identifier that the runtime allowlist matches against, so an empty value could never authorize anything and is refused at config load time instead of silently dead-matching.

Source

Thrown at crates/zeroclaw-config/src/schema.rs:21847

                    .iter()
                    .map(|s| s.trim())
                    .collect()
            };

        let mut seen_gws_operations = std::collections::HashSet::new();
        for (i, operation) in self.google_workspace.allowed_operations.iter().enumerate() {
            let service = operation.service.trim();
            let resource = operation.resource.trim();

            if service.is_empty() {
                validation_bail!(
                    RequiredFieldEmpty,
                    format!("google_workspace.allowed_operations[{i}].service"),
                    "google_workspace.allowed_operations[{i}].service must not be empty"
                );
            }
            if resource.is_empty() {
                anyhow::bail!(
                    "google_workspace.allowed_operations[{i}].resource must not be empty"
                );
            }

            if !effective_services.contains(service) {
                anyhow::bail!(
                    "google_workspace.allowed_operations[{i}].service '{service}' is not in the \
                     effective allowed_services; this entry can never match at runtime"
                );
            }
            if !service
                .chars()
                .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '-')
            {
                anyhow::bail!(
                    "google_workspace.allowed_operations[{i}].service contains invalid characters: {service}"
                );
            }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set resource to a real Google API resource name for that service (e.g. "calendarList" for service "calendar", "files" for "drive")
  2. Remove the whole [[google_workspace.allowed_operations]] block if you do not need that grant
  3. Re-run the config validation command after the edit to confirm the entry passes

Example fix

# before
[[google_workspace.allowed_operations]]
service = "calendar"
resource = ""
methods = ["list"]

# after
[[google_workspace.allowed_operations]]
service = "calendar"
resource = "calendarList"
methods = ["list"]
Defensive patterns

Strategy: validation

Validate before calling

// Rust: pre-flight the field before calling Config::validate()
fn has_gws_resource(op: &zeroclaw_config::schema::GwsOperation) -> bool {
    !op.resource.trim().is_empty()
}
// for op in &config.google_workspace.allowed_operations {
//     assert!(has_gws_resource(op), "missing resource on operation");
// }

Type guard

fn is_non_empty_resource(v: &str) -> bool { !v.trim().is_empty() }

Try / catch

// validate() returns anyhow::Result; branch on the message prefix
match config.validate() {
    Ok(()) => {}
    Err(e) if e.to_string().starts_with("google_workspace.allowed_operations") => {
        eprintln!("bad google_workspace config: {e}"); // fix the TOML, do not retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Loading or validating a zeroclaw config in which an entry under [[google_workspace.allowed_operations]] has resource = "" (or only whitespace), e.g. at daemon startup, config reload, or any code path that calls Config::validate() on a deserialized Config.

Common situations: Copy-pasting an operation template and forgetting to fill in resource; scaffolding configs generated with placeholder empty strings; intending a service-wide grant (no resource filter), which this schema does not support.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/1dab05e8a166952b. Report an issue: GitHub.