{"record":{"id":"15ea4dd3456a46ce","repo":"zeroclaw-labs/zeroclaw","slug":"google-workspace-allowed-operations-i-resource-15ea4d","errorCode":null,"errorMessage":"google_workspace.allowed_operations[{i}].resource contains invalid characters: {resource}","messagePattern":"google_workspace\\.allowed_operations\\[(.+?)\\]\\.resource contains invalid characters: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":21873,"sourceCode":"                     effective allowed_services; this entry can never match at runtime\"\n                );\n            }\n            if !service\n                .chars()\n                .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '-')\n            {\n                anyhow::bail!(\n                    \"google_workspace.allowed_operations[{i}].service contains invalid characters: {service}\"\n                );\n            }\n            // Unlike service IDs, resource/sub_resource/method names are camelCase\n            // in the Google APIs (calendarList, quickAdd, batchUpdate), so\n            // uppercase must be accepted here and in the runtime tool check.\n            if !resource\n                .chars()\n                .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n            {\n                anyhow::bail!(\n                    \"google_workspace.allowed_operations[{i}].resource contains invalid characters: {resource}\"\n                );\n            }\n\n            if let Some(ref sub_resource) = operation.sub_resource {\n                let sub = sub_resource.trim();\n                if sub.is_empty() {\n                    anyhow::bail!(\n                        \"google_workspace.allowed_operations[{i}].sub_resource must not be empty when present\"\n                    );\n                }\n                if !sub\n                    .chars()\n                    .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n                {\n                    anyhow::bail!(\n                        \"google_workspace.allowed_operations[{i}].sub_resource contains invalid characters: {sub}\"\n                    );","sourceCodeStart":21855,"sourceCodeEnd":21891,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L21855-L21891","documentation":"Config::validate() checks that allowed_operations[].resource contains only ASCII alphanumeric characters (both cases), '_' and '-'. Unlike service IDs, camelCase is deliberately accepted here because Google API resource names are camelCase (calendarList, quickUpdate); spaces, dots, slashes and other punctuation are rejected so the resource can be matched unambiguously against runtime tool identifiers.","triggerScenarios":"An operation entry with resource = \"calendar list\", resource = \"files.attachments\", or resource = \"a/b\" in the config file, surfaced when Config::validate() runs at startup or config check.","commonSituations":"Transcribing REST paths (\"calendar/v3/calendarList\") or dot-separated names from API documentation instead of the bare resource name; inserting spaces while hand-editing long TOML arrays.","solutions":["Use the bare camelCase resource name from the Google API (\"calendarList\", \"files\", \"messages\")","Replace spaces with '_' or '-' if you need a separator, or drop path prefixes entirely","Verify the value against the service's API surface so the runtime check can actually match"],"exampleFix":"# before\n[[google_workspace.allowed_operations]]\nservice = \"calendar\"\nresource = \"calendar/v3/calendarList\"\nmethods = [\"list\"]\n\n# after\n[[google_workspace.allowed_operations]]\nservice = \"calendar\"\nresource = \"calendarList\"\nmethods = [\"list\"]","handlingStrategy":"validation","validationCode":"fn is_valid_gws_resource(s: &str) -> bool {\n    !s.trim().is_empty()\n        && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n}","typeGuard":"fn is_valid_gws_resource(s: &str) -> bool {\n    s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n}","tryCatchPattern":"match config.validate() {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"resource contains invalid characters\") => {\n        // strip path segments/dots; keep the bare camelCase resource name\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Copy resource names from the API's resource listing, not from REST URL paths","Remember resource allows camelCase but not '.', '/', or spaces","Add a scratch test that validates your production config file"],"tags":["config","google-workspace","validation","naming"],"backgroundTag":"config-field-invalid-characters","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}