{"record":{"id":"ac105b04c629d33d","repo":"shadowsocks/shadowsocks-rust","slug":"plugin-mode-must-be-one-of-tcp-only-default-ac105b","errorCode":null,"errorMessage":"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`","messagePattern":"plugin-mode must be one of `tcp_only` \\(default\\), `udp_only` and `tcp_and_udp`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/service/manager.rs","lineNumber":387,"sourceCode":"\n            if let Some(t) = matches.get_one::<u64>(\"TIMEOUT\") {\n                manager_config.timeout = Some(Duration::from_secs(*t));\n            }\n\n            if let Some(sh) = matches.get_one::<ManagerServerHost>(\"SERVER_HOST\").cloned() {\n                manager_config.server_host = sh;\n            }\n\n            if let Some(p) = matches.get_one::<String>(\"PLUGIN\").cloned() {\n                manager_config.plugin = Some(PluginConfig {\n                    plugin: p,\n                    plugin_opts: matches.get_one::<String>(\"PLUGIN_OPT\").cloned(),\n                    plugin_args: Vec::new(),\n                    plugin_mode: matches\n                        .get_one::<String>(\"PLUGIN_MODE\")\n                        .map(|x| {\n                            x.parse::<Mode>()\n                                .expect(\"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\")\n                        })\n                        .unwrap_or(Mode::TcpOnly),\n                });\n            }\n\n            #[cfg(unix)]\n            if let Some(server_mode) = matches.get_one::<ManagerServerMode>(\"MANAGER_SERVER_MODE\").cloned() {\n                manager_config.server_mode = server_mode;\n            }\n\n            #[cfg(unix)]\n            if let Some(server_working_directory) =\n                matches.get_one::<PathBuf>(\"MANAGER_SERVER_WORKING_DIRECTORY\").cloned()\n            {\n                manager_config.server_working_directory = server_working_directory;\n            }\n        }\n","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/service/manager.rs#L369-L405","documentation":"The manager service parses `PLUGIN_MODE` into the `Mode` enum (`tcp_only` / `udp_only` / `tcp_and_udp`) and panics with this message when the string doesn't match any variant. This value controls whether the SIP003 plugin handles TCP only, UDP only, or both.","triggerScenarios":"Passing `--plugin-mode` (or equivalent) with anything other than the exact strings `tcp_only`, `udp_only`, or `tcp_and_udp`, e.g. `tcp`, `TCP_ONLY`, or `tcp-and-udp`.","commonSituations":"Users guessing the separator (`-` vs `_`), copying values from other proxy tools, or capitalizing the value from JSON/YAML config conventions.","solutions":["Use exactly one of: `tcp_only`, `udp_only`, `tcp_and_udp` (lowercase, underscores)","Omit `--plugin-mode` entirely to get the default `tcp_only`","Check the config file for a `plugin_mode` value and normalize it to a valid variant"],"exampleFix":"// before\n--plugin-mode \"TCP-AND-UDP\"\n// after\n--plugin-mode \"tcp_and_udp\"","handlingStrategy":"validation","validationCode":"const MODES: &[&str] = &[\"tcp_only\", \"udp_only\", \"tcp_and_udp\"];\nif let Some(m) = plugin_mode.as_deref() {\n    assert!(MODES.contains(&m), \"plugin-mode must be one of {MODES:?}\");\n}","typeGuard":"fn is_valid_plugin_mode(s: &str) -> bool {\n    matches!(s, \"tcp_only\" | \"udp_only\" | \"tcp_and_udp\")\n}","tryCatchPattern":"// use parse and report instead of expect\nlet mode: Mode = s.parse().map_err(|_| anyhow!(\"plugin-mode must be tcp_only|udp_only|tcp_and_udp\"))?;","preventionTips":["Use lowercase with underscores exactly","Omit the flag when the default (tcp_only) is fine","Validate generated configs before deployment"],"tags":["cli","plugin","enum","parsing"],"backgroundTag":"invalid-enum-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}