zeroclaw-labs/zeroclaw · error
google_workspace.allowed_operations[{i}].service '{service}'
Error message
google_workspace.allowed_operations[{i}].service '{service}' is not in the effective allowed_services; this entry can never match at runtime What it means
This is a cross-field consistency check inside Config::validate(): every allowed_operations entry's `service` must be contained in the effective allowed_services set, which is the explicit google_workspace.allowed_services list, or the built-in DEFAULT_GWS_SERVICES when that list is left empty (schema.rs:21823). Because the runtime tool gate consults allowed_services first, an operation naming an unlisted service could never match; validate() fails fast at load time rather than accepting a dead entry.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:21853
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}"
);
}
// Unlike service IDs, resource/sub_resource/method names are camelCase
// in the Google APIs (calendarList, quickAdd, batchUpdate), so
// uppercase must be accepted here and in the runtime tool check.
if !resource
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')View on GitHub (pinned to 88bb9c8533)
Solutions
- Add the operation's service ID to google_workspace.allowed_services (e.g. "gmail")
- If the entry is stale, remove that [[google_workspace.allowed_operations]] block instead
- Check the service ID spelling against the DEFAULT_GWS_SERVICES list / Google API naming (calendar, gmail, drive, ...)
Example fix
# before [google_workspace] allowed_services = ["calendar"] [[google_workspace.allowed_operations]] service = "gmail" resource = "messages" methods = ["get"] # after [google_workspace] allowed_services = ["calendar", "gmail"] [[google_workspace.allowed_operations]] service = "gmail" resource = "messages" methods = ["get"]
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: operation services must be a subset of the effective allowed set
let effective: std::collections::HashSet<&str> = if cfg.google_workspace.allowed_services.is_empty() {
DEFAULT_GWS_SERVICES.iter().copied().collect()
} else {
cfg.google_workspace.allowed_services.iter().map(|s| s.trim()).collect()
};
for op in &cfg.google_workspace.allowed_operations {
if !effective.contains(op.service.trim()) { /* reject before validate() */ }
} Type guard
fn op_service_allowed(service: &str, effective: &std::collections::HashSet<&str>) -> bool {
effective.contains(service.trim())
} Try / catch
match config.validate() {
Ok(()) => {}
Err(e) if e.to_string().contains("is not in the effective allowed_services") => {
// reconcile allowed_services vs allowed_operations, then reload
}
Err(e) => return Err(e),
} Prevention
- Define allowed_services once and derive operation entries from it in your config generator
- Add a unit test asserting operation services are a subset of allowed_services
- When trimming allowed_services, grep allowed_operations for removed services in the same change
When it happens
Trigger: (a) google_workspace.allowed_services = ["calendar"] together with an operation entry whose service = "gmail"; (b) allowed_services omitted (defaults apply) and an operation uses a service ID outside DEFAULT_GWS_SERVICES, e.g. a typo like "gcal".
Common situations: Adding an operation for a new Google service but forgetting to widen allowed_services; later trimming allowed_services while stale operation entries remain; typos in service IDs that still pass the character check.
Related errors
- google_workspace.allowed_operations[{i}].resource must not b
- Missing [channels.telegram.{}] section. Run `zeroclaw config
- google_workspace.allowed_operations[{i}].service contains in
- google_workspace.allowed_operations[{i}].resource contains i
- google_workspace.allowed_operations[{i}].sub_resource must n
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ff5c9ca5a394c6b8.
Report an issue: GitHub.