zeroclaw-labs/zeroclaw · error
google_workspace.allowed_operations[{i}].sub_resource contai
Error message
google_workspace.allowed_operations[{i}].sub_resource contains invalid characters: {sub} What it means
Config::validate() applies the same identifier rule to allowed_operations[].sub_resource as to resource: ASCII alphanumeric (camelCase allowed), '_' and '-' only. The sub-resource becomes a segment of the runtime tool key the allowlist matches on, so spaces, dots, slashes, or non-ASCII characters are rejected at config load time.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:21889
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
{
anyhow::bail!(
"google_workspace.allowed_operations[{i}].resource contains invalid characters: {resource}"
);
}
if let Some(ref sub_resource) = operation.sub_resource {
let sub = sub_resource.trim();
if sub.is_empty() {
anyhow::bail!(
"google_workspace.allowed_operations[{i}].sub_resource must not be empty when present"
);
}
if !sub
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
{
anyhow::bail!(
"google_workspace.allowed_operations[{i}].sub_resource contains invalid characters: {sub}"
);
}
}
if operation.methods.is_empty() {
validation_bail!(
RequiredFieldEmpty,
format!("google_workspace.allowed_operations[{i}].methods"),
"google_workspace.allowed_operations[{i}].methods must not be empty"
);
}
let mut seen_methods = std::collections::HashSet::new();
for (j, method) in operation.methods.iter().enumerate() {
let normalized = method.trim();
if normalized.is_empty() {
anyhow::bail!(View on GitHub (pinned to 88bb9c8533)
Solutions
- Use the bare sub-resource identifier ("attachments", "replies")
- Replace separators with '_' or '-','Drop path/version prefixes that belong to the URL, not the tool identifier
Example fix
# before [[google_workspace.allowed_operations]] service = "drive" resource = "files" sub_resource = "file.attachments" methods = ["get"] # after [[google_workspace.allowed_operations]] service = "drive" resource = "files" sub_resource = "attachments" methods = ["get"]
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_gws_sub_resource(s: &str) -> bool {
s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
} Type guard
fn is_valid_gws_sub_resource(s: &str) -> bool {
!s.is_empty() && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
} Try / catch
match config.validate() {
Ok(()) => {}
Err(e) if e.to_string().contains("sub_resource contains invalid characters") => {
// replace dots/slashes with '_' or drop them; re-validate
}
Err(e) => return Err(e),
} Prevention
- Use bare identifiers for sub-resources (attachments, replies)
- Avoid locale-specific characters in machine identifiers
- Validate configs in CI with the same binary version that runs in production
When it happens
Trigger: An operation entry with sub_resource = "file attachments", sub_resource = "v2.items", or sub_resource = "café" being validated via Config::validate().
Common situations: Copying dotted names from Google API docs, translating REST path segments verbatim, or locale-specific characters slipping into hand-written config.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- google_workspace.allowed_operations[{i}].service contains in
- google_workspace.allowed_operations[{i}].resource contains i
- google_workspace.allowed_operations[{i}].methods[{j}] contai
- google_workspace.allowed_operations[{i}].resource must not b
- 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/efb10783edcd7413.
Report an issue: GitHub.