{"record":{"id":"7c3ab288a34ac706","repo":"zeroclaw-labs/zeroclaw","slug":"tunnel-pinggy-region-must-be-one-of-us-eu-ap-b","errorCode":null,"errorMessage":"tunnel.pinggy.region must be one of: us, eu, ap, br, au (or omitted for auto)","messagePattern":"tunnel\\.pinggy\\.region must be one of: us, eu, ap, br, au \\(or omitted for auto\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":22056,"sourceCode":"                    \"notion.input_property must not be empty\"\n                );\n            }\n            if self.notion.result_property.trim().is_empty() {\n                validation_bail!(\n                    RequiredFieldEmpty,\n                    \"notion.result_property\",\n                    \"notion.result_property must not be empty\"\n                );\n            }\n        }\n\n        // Pinggy tunnel region — validate allowed values (case-insensitive, auto-lowercased at runtime).\n        if let Some(ref pinggy) = self.tunnel.pinggy\n            && let Some(ref region) = pinggy.region\n        {\n            let r = region.trim().to_ascii_lowercase();\n            if !r.is_empty() && !matches!(r.as_str(), \"us\" | \"eu\" | \"ap\" | \"br\" | \"au\") {\n                anyhow::bail!(\n                    \"tunnel.pinggy.region must be one of: us, eu, ap, br, au (or omitted for auto)\"\n                );\n            }\n        }\n\n        // Jira\n        if self.jira.enabled {\n            if self.jira.base_url.trim().is_empty() {\n                anyhow::bail!(\"jira.base_url must not be empty when jira.enabled = true\");\n            }\n            if self.jira.api_token.trim().is_empty()\n                && std::env::var(\"JIRA_API_TOKEN\")\n                    .unwrap_or_default()\n                    .trim()\n                    .is_empty()\n            {\n                anyhow::bail!(\n                    \"jira.api_token must be set (or JIRA_API_TOKEN env var) when jira.enabled = true\"","sourceCodeStart":22038,"sourceCodeEnd":22074,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L22038-L22074","documentation":"Validates tunnel.pinggy.region in Config::validate. When a Pinggy tunnel region is configured, it is trimmed and ASCII-lowercased, then must be one of the five supported Pinggy regions: us, eu, ap, br, au. An empty string after trim is allowed (means auto-selection), and case does not matter because of the lowercasing — only the region code itself must match. Any other value (country names, full words, unsupported regions) is rejected.","triggerScenarios":"Configuring tunnel.pinggy with `region = \"usa\"`, \"japan\", \"in\", \"EU \" (fine, lowercased) or any code outside {us, eu, ap, br, au}; passing a country code where a Pinggy region code is expected; typos like \"au \" are fine (trimmed) but \"AUS\" is not.","commonSituations":"User copies an AWS-style region string (e.g. \"us-east-1\") into the Pinggy config; user guesses a region Pinggy does not offer; values harvested from cloud provider configs pasted wholesale.","solutions":["Change tunnel.pinggy.region to one of: us, eu, ap, br, au (case-insensitive)","Or delete the region key entirely to let Pinggy auto-select the closest region"],"exampleFix":"# before\n[tunnel.pinggy]\nregion = \"us-east-1\"\n\n# after\n[tunnel.pinggy]\nregion = \"us\"","handlingStrategy":"validation","validationCode":"const PINGGY_REGIONS: [&str; 5] = [\"us\", \"eu\", \"ap\", \"br\", \"au\"];\nfn pinggy_region_ok(region: Option<&str>) -> bool {\n    match region {\n        None => true,\n        Some(r) => { let r = r.trim().to_ascii_lowercase(); r.is_empty() || PINGGY_REGIONS.contains(&r.as_str()) }\n    }\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = cfg.validate() {\n    if e.to_string().contains(\"tunnel.pinggy.region\") {\n        eprintln!(\"region must be us/eu/ap/br/au or omitted; got: {:?}\", cfg.tunnel.pinggy.as_ref().and_then(|p| p.region.clone()));\n    }\n}","preventionTips":["Use a config schema/enum for region in generated configs instead of free text","Omit the region key when auto-selection is acceptable — fewer fields, fewer failures"],"tags":["tunnel","pinggy","config","validation","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}