{"record":{"id":"e5f5c9c4e5c2f446","repo":"wasmerio/wasmer","slug":"user-agent-must-not-be-empty","errorCode":null,"errorMessage":"user agent must not be empty","messagePattern":"user agent must not be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"lib/backend-api/src/client.rs","lineNumber":45,"sourceCode":"\nimpl WasmerClient {\n    /// Env var used to enable logging of request variables.\n    ///\n    /// This is somewhat dangerous since it can log sensitive information, hence\n    /// it is gated by a custom env var.\n    const ENV_VAR_LOG_VARIABLES: &'static str = \"WASMER_API_INSECURE_LOG_VARIABLES\";\n\n    pub fn graphql_endpoint(&self) -> &Url {\n        &self.graphql_endpoint\n    }\n\n    pub fn auth_token(&self) -> Option<&str> {\n        self.auth_token.as_deref()\n    }\n\n    fn parse_user_agent(user_agent: &str) -> Result<reqwest::header::HeaderValue, anyhow::Error> {\n        if user_agent.is_empty() {\n            bail!(\"user agent must not be empty\");\n        }\n        user_agent\n            .parse()\n            .with_context(|| format!(\"invalid user agent: '{user_agent}'\"))\n    }\n\n    pub fn new_with_client(\n        client: reqwest::Client,\n        graphql_endpoint: Url,\n        user_agent: &str,\n    ) -> Result<Self, anyhow::Error> {\n        let log_variables = {\n            let v = std::env::var(Self::ENV_VAR_LOG_VARIABLES).unwrap_or_default();\n            match v.as_str() {\n                \"1\" | \"true\" => true,\n                \"0\" | \"false\" => false,\n                // Default case if not provided.\n                \"\" => false,","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/backend-api/src/client.rs#L27-L63","documentation":"WasmerClient's parse_user_agent rejects an empty user-agent string with this bail before ever building the HTTP client. A reqwest HeaderValue built from an empty string would be useless/invalid for the backend API, so the constructor treats it as a configuration error and returns an anyhow error.","triggerScenarios":"Constructing WasmerClient (new / new_with_client path) with user_agent = \"\" — e.g. WasmerClient::new(url, \"\") or reading a user agent from an unset variable without a default.","commonSituations":"CI scripts or CLI wrappers passing an empty UA; an env var like WASMER_USER_AGENT set to empty; forgotten default value in library configuration.","solutions":["Pass a non-empty user agent string, e.g. \"my-app/1.0\" or concat!(env!(\"CARGO_PKG_NAME\"), \"/\", env!(\"CARGO_PKG_VERSION\")).","Add a fallback default when the value comes from config/env: if empty, substitute a sensible default.","Trim whitespace and validate before constructing the client."],"exampleFix":"// before\nlet client = WasmerClient::new(endpoint, \"\")?;\n// after\nlet ua = if user_agent.trim().is_empty() {\n    format!(\"{}/{}\", env!(\"CARGO_PKG_NAME\"), env!(\"CARGO_PKG_VERSION\"))\n} else { user_agent.to_string() };\nlet client = WasmerClient::new(endpoint, ua)?;","handlingStrategy":"validation","validationCode":"fn build_user_agent(ua: &str) -> anyhow::Result<String> {\n    let ua = ua.trim();\n    if ua.is_empty() {\n        anyhow::bail!(\"user agent must not be empty\");\n    }\n    Ok(ua.to_string())\n}","typeGuard":"fn is_valid_user_agent(ua: &str) -> bool { !ua.trim().is_empty() }","tryCatchPattern":"// construction is fallible anyway\nlet client = WasmerClient::new(endpoint, ua)\n    .map_err(|e| e.context(\"invalid client configuration (check user_agent)\"))?;","preventionTips":["Default user agents to CARGO_PKG_NAME/CARGO_PKG_VERSION instead of empty strings","Trim and validate UA strings at config-load time","Never forward raw env vars into user_agent without a default"],"tags":["config","validation","http-client","backend-api"],"backgroundTag":"invalid-user-agent","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}