{"record":{"id":"cb4e49f365a25d0e","repo":"clockworklabs/SpacetimeDB","slug":"invalid-http-method","errorCode":null,"errorMessage":"Invalid HTTP method","messagePattern":"Invalid HTTP method","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/host/instance_env.rs","lineNumber":1220,"sourceCode":"        method,\n        headers,\n        timeout,\n        uri,\n        version,\n    } = request;\n\n    let (mut request, ()) = http::Request::new(()).into_parts();\n    request.method = match method {\n        st_http::Method::Get => http::Method::GET,\n        st_http::Method::Head => http::Method::HEAD,\n        st_http::Method::Post => http::Method::POST,\n        st_http::Method::Put => http::Method::PUT,\n        st_http::Method::Delete => http::Method::DELETE,\n        st_http::Method::Connect => http::Method::CONNECT,\n        st_http::Method::Options => http::Method::OPTIONS,\n        st_http::Method::Trace => http::Method::TRACE,\n        st_http::Method::Patch => http::Method::PATCH,\n        st_http::Method::Extension(method) => http::Method::from_bytes(method.as_bytes()).expect(\"Invalid HTTP method\"),\n    };\n    // The error type here, `http::uri::InvalidUri`, doesn't contain the URI itself,\n    // so it's safe to return and to log.\n    // See https://docs.rs/http/1.3.1/src/http/uri/mod.rs.html#120-141 .\n    request.uri = uri.try_into()?;\n    request.version = match version {\n        st_http::Version::Http09 => http::Version::HTTP_09,\n        st_http::Version::Http10 => http::Version::HTTP_10,\n        st_http::Version::Http11 => http::Version::HTTP_11,\n        st_http::Version::Http2 => http::Version::HTTP_2,\n        st_http::Version::Http3 => http::Version::HTTP_3,\n    };\n    request.headers = headers\n        .into_iter()\n        .map(|(k, v)| {\n            Ok((\n                // The error type here, `http::header::InvalidHeaderName`, doesn't contain the header name itself,\n                // so it's safe to return and to log.","sourceCodeStart":1202,"sourceCodeEnd":1238,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/core/src/host/instance_env.rs#L1202-L1238","documentation":"SpacetimeDB modules can issue HTTP requests; non-standard methods arrive as `st_http::Method::Extension(bytes)` and are converted with `http::Method::from_bytes(...).expect(\"Invalid HTTP method\")`. `from_bytes` fails when the bytes are not a valid RFC 7230 token: an empty string, embedded spaces/control characters, or characters outside the token set such as `/`, `?`, `,`, or non-ASCII.","triggerScenarios":"Calling the module HTTP client API with an extension method like \"FOO BAR\", an empty string, a method with trailing CR/LF or whitespace, or non-ASCII bytes (e.g. \"MÉTHODE\") — anything outside A-Z a-z 0-9 and !#$%&'*+-.^_`|~.","commonSituations":"Building the method dynamically from user input or config without validation; WebDAV-style custom verbs (\"VERSION-CONTROL\" is valid) concatenated with stray whitespace/newlines; lowercase custom verbs are accepted but injected separators are not.","solutions":["Validate the method before the request: non-empty and every byte an RFC 7230 token character (A-Z a-z 0-9 !#$%&'*+-.^_`|~).","Uppercase and hard-code known custom verbs from an enum instead of passing arbitrary strings.","If the method originates from untrusted input, reject invalid tokens early with a reducer error instead of letting the module panic."],"exampleFix":"// before: arbitrary string panics on invalid bytes\nlet method = st_http::Method::Extension(method_str.into());\n\n// after: validate the token first\nfn is_http_token(s: &str) -> bool {\n    !s.is_empty() && s.bytes().all(|b|\n        b.is_ascii_alphanumeric() || matches!(b, b'-' | b'.' | b'_' | b'~' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\\'' | b'*' | b'+' | b'^' | b'`' | b'|'))\n}\nassert!(is_http_token(&method_str), \"invalid HTTP method token\");","handlingStrategy":"validation","validationCode":"fn is_http_token(s: &str) -> bool {\n    !s.is_empty() && s.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'.' | b'_' | b'~' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\\'' | b'*' | b'+' | b'^' | b'`' | b'|'))\n}\nassert!(is_http_token(&custom_method), \"invalid HTTP method\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass unvalidated strings as HTTP methods from modules.","Map allowed verbs from an enum and reject unknown ones at the boundary.","Test module HTTP helpers with odd verbs before publishing."],"tags":["rust","http","spacetimedb-module","validation","method"],"backgroundTag":"invalid-http-method","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}