{"record":{"id":"668ece8deb7a2eb3","repo":"risingwavelabs/risingwave","slug":"http-sink-method-must-be-post-or-put-got-method","errorCode":null,"errorMessage":"HTTP sink method must be POST or PUT, got '{method}'","messagePattern":"HTTP sink method must be POST or PUT, got '(.+?)'","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/http.rs","lineNumber":118,"sourceCode":"    schema: &Schema,\n    url: Option<&str>,\n    method: Option<&str>,\n    content_type: Option<&str>,\n    headers: &BTreeMap<String, String>,\n    unknown_fields: std::collections::HashMap<String, String>,\n) -> Result<HttpSink> {\n    if !is_append_only && !ignore_delete {\n        return Err(SinkError::Config(anyhow!(\n            \"HTTP sink only supports append-only mode\"\n        )));\n    }\n\n    let method = match method {\n        None => reqwest::Method::POST,\n        Some(method) if method.eq_ignore_ascii_case(\"POST\") => reqwest::Method::POST,\n        Some(method) if method.eq_ignore_ascii_case(\"PUT\") => reqwest::Method::PUT,\n        Some(method) => {\n            return Err(SinkError::Config(anyhow!(\n                \"HTTP sink method must be POST or PUT, got '{method}'\"\n            )));\n        }\n    };\n\n    let fields = schema.fields();\n    let (payload_index, url, payload_type) = if fields.len() == 1 {\n        let Some(url) = url else {\n            return Err(SinkError::Config(anyhow!(\n                \"HTTP sink requires url option when schema has exactly 1 column\"\n            )));\n        };\n        let url = url\n            .parse()\n            .context(\"invalid URL\")\n            .map_err(SinkError::Config)?;\n        (0, HttpUrl::Static(url), fields[0].data_type.clone())\n    } else {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/http.rs#L100-L136","documentation":"Validation guard in validate_http_sink (called via try_from) that normalizes the user-supplied `method` option: only POST and PUT are accepted; any other value (e.g. GET, DELETE, or a misspelled method) is rejected before a reqwest::Method is constructed. The message interpolates the offending method string.","triggerScenarios":"`validate_http_sink` receives method=Some(m) where m is not 'POST' or 'PUT' (case-insensitive).","commonSituations":"User sets method='GET' hoping to trigger webhooks via query; copy-pasting method options from other sinks; typo like 'PosT' is fine, but 'PATCH'/'DELETE' are not.","solutions":["Set method='POST' (default) or method='PUT' in the WITH options","Remove the method option to accept the POST default","Use a different delivery mechanism if you need other verbs"],"exampleFix":"// before\nWITH (connector='http', url='...', method='PATCH')\n// after\nWITH (connector='http', url='...', method='POST')","handlingStrategy":"validation","validationCode":"if let Some(m) = options.get(\"method\") {\n    let ok = m.eq_ignore_ascii_case(\"POST\") || m.eq_ignore_ascii_case(\"PUT\");\n    if !ok { return Err(format!(\"method must be POST or PUT, got '{m}'\")); }\n}","typeGuard":null,"tryCatchPattern":"match sink::try_create(props) {\n    Err(e) if e.to_string().contains(\"method must be POST or PUT\") => {\n        log::error!(\"fix the method option: {e}\");\n    }\n    r => r?,\n}","preventionTips":["Only set method for POST/PUT targets","Omit the method option to get the POST default","Check webhook endpoint documentation for supported verbs"],"tags":["http","sink","method","config","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}