{"record":{"id":"ffdd5737d6aa7796","repo":"zeroclaw-labs/zeroclaw","slug":"unsupported-http-method-method-supported-get","errorCode":null,"errorMessage":"Unsupported HTTP method: {method}. Supported: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS","messagePattern":"Unsupported HTTP method: (.+?)\\. Supported: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/http_request.rs","lineNumber":239,"sourceCode":"        )?;\n\n        Ok(ValidatedHttpRequestTarget {\n            url: policy.url,\n            host: policy.host,\n            resolved_addrs,\n        })\n    }\n\n    fn validate_method(&self, method: &str) -> anyhow::Result<reqwest::Method> {\n        match method.to_uppercase().as_str() {\n            \"GET\" => Ok(reqwest::Method::GET),\n            \"POST\" => Ok(reqwest::Method::POST),\n            \"PUT\" => Ok(reqwest::Method::PUT),\n            \"DELETE\" => Ok(reqwest::Method::DELETE),\n            \"PATCH\" => Ok(reqwest::Method::PATCH),\n            \"HEAD\" => Ok(reqwest::Method::HEAD),\n            \"OPTIONS\" => Ok(reqwest::Method::OPTIONS),\n            _ => anyhow::bail!(\n                \"Unsupported HTTP method: {method}. Supported: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS\"\n            ),\n        }\n    }\n\n    fn parse_headers(&self, headers: &serde_json::Value) -> anyhow::Result<HeaderMap> {\n        let mut result = HeaderMap::new();\n        if let Some(obj) = headers.as_object() {\n            for (key, value) in obj {\n                let Some(str_val) = value.as_str() else {\n                    anyhow::bail!(\"Header '{key}' value must be a string, got: {}\", value);\n                };\n                let header_name = HeaderName::from_str(key)\n                    .map_err(|e| anyhow::Error::msg(format!(\"Invalid header name '{key}': {e}\")))?;\n                let header_value = HeaderValue::from_str(str_val).map_err(|e| {\n                    anyhow::Error::msg(format!(\"Invalid value for header '{key}': {e}\"))\n                })?;\n                result.insert(header_name, header_value);","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/http_request.rs#L221-L257","documentation":"Thrown by HttpRequestTool::validate_method (crates/zeroclaw-tools/src/http_request.rs:239) when the method string, after to_uppercase(), is not one of GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. The tool intentionally exposes only these seven methods; anything else (including empty strings and methods with trailing whitespace) is rejected before the request is built. Lowercase input like \"get\" is accepted because it is uppercased first.","triggerScenarios":"args.method = \"TRACE\", \"CONNECT\", or \"PURGE\" (CDN purge verbs); method = \"\" (empty string matches nothing); method = \"GET \" with a trailing space or newline (does not equal \"GET\" after uppercasing); a WebDAV verb like \"PROPFIND\".","commonSituations":"Wrapping CDN or cache-admin APIs that need PURGE; WebDAV integrations; LLM-produced method strings with stray whitespace; forwarding a raw method header from another request verbatim.","solutions":["Use one of the seven supported methods; for cache purge, switch the API to its POST- or DELETE-based variant if it has one.","Trim the method string before passing it (method.trim()), since interior/trailing whitespace defeats the match.","If you control the server, expose the operation under a supported verb (e.g. POST /cache/purge instead of PURGE /)."],"exampleFix":"// before\nlet args = json!({\"url\": \"https://cdn.example.com/img\", \"method\": \"PURGE\"});\n\n// after\nlet args = json!({\"url\": \"https://cdn.example.com/cache/purge\", \"method\": \"POST\"});","handlingStrategy":"validation","validationCode":"const SUPPORTED: &[&str] = &[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\"];\nfn method_supported(method: &str) -> bool {\n    SUPPORTED.contains(&method.to_uppercase().as_str())\n}","typeGuard":"fn is_supported_method(method: &str) -> bool {\n    method.to_uppercase().trim().is_empty() == false\n        && SUPPORTED.contains(&method.to_uppercase().trim())\n}","tryCatchPattern":"let result = tool.execute(args).await?;\nif let Some(err) = &result.error {\n    if err.contains(\"Unsupported HTTP method\") {\n        // fall back to the closest supported verb the API also accepts (often POST)\n    }\n}","preventionTips":["Constrain the method in your tool-calling schema to the seven allowed enum values.","Trim method strings before sending; trailing whitespace defeats the match.","Pick APIs that expose operations via standard verbs."],"tags":["http","method","validation","zeroclaw"],"backgroundTag":"unsupported-http-method","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}