{"record":{"id":"1ba9931b61882c7f","repo":"rathole-org/rathole","slug":"cannot-determine-running-as-a-server-or-a-client","errorCode":null,"errorMessage":"Cannot determine running as a server or a client","messagePattern":"Cannot determine running as a server or a client","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/lib.rs","lineNumber":124,"sourceCode":"                    let _ = service_update_tx.send(ev).await;\n                }\n            }\n        }\n    }\n\n    let _ = shutdown_tx.send(true);\n\n    Ok(())\n}\n\nasync fn run_instance(\n    config: Config,\n    args: Cli,\n    shutdown_rx: broadcast::Receiver<bool>,\n    service_update: mpsc::Receiver<ConfigChange>,\n) -> Result<()> {\n    match determine_run_mode(&config, &args) {\n        RunMode::Undetermine => panic!(\"Cannot determine running as a server or a client\"),\n        RunMode::Client => {\n            #[cfg(not(feature = \"client\"))]\n            crate::helper::feature_not_compile(\"client\");\n            #[cfg(feature = \"client\")]\n            run_client(config, shutdown_rx, service_update).await\n        }\n        RunMode::Server => {\n            #[cfg(not(feature = \"server\"))]\n            crate::helper::feature_not_compile(\"server\");\n            #[cfg(feature = \"server\")]\n            run_server(config, shutdown_rx, service_update).await\n        }\n    }\n}\n\n#[derive(PartialEq, Eq, Debug)]\nenum RunMode {\n    Server,","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/rathole-org/rathole/blob/a292f7ed5402f840415fc6a53827da2f34337856/src/lib.rs#L106-L142","documentation":"run_instance panics when determine_run_mode cannot decide whether rathole should act as a server or a client. The run mode is derived from the config file contents and CLI args, and RunMode::Undetermine means neither was conclusive. Since the process cannot proceed without a mode, it aborts with this panic.","triggerScenarios":"Running rathole with a config that has neither a [server] nor a [client] section (or an empty one) and no --server/--client CLI flag to disambiguate.","commonSituations":"Empty or mistyped config file (e.g. writing [sever] instead of [server]); pointing rathole at the wrong TOML file; passing only the transport section in config.","solutions":["Add a [client] or [server] section to the config TOML","Pass an explicit flag: rathole --server config.toml (or --client)","Fix typos in the config section names and re-run","Verify rathole is reading the config file you think it is (check the path argument)"],"exampleFix":"// before: config.toml\n[transport]\ntype = \"tcp\"\n\n// after\n[client]\nremote_addr = \"example.com:2333\"\n\n[client.services]\nssh = { local_addr = \"127.0.0.1:22\" }","handlingStrategy":"validation","validationCode":"// Validate the config has exactly one run-mode section before launching:\nimport re, sys\ncfg = open('config.toml').read()\nhas_server = re.search(r'^\\s*\\[server\\]', cfg, re.M) is not None\nhas_client = re.search(r'^\\s*\\[client\\]', cfg, re.M) is not None\nif has_server == has_client:\n    sys.exit('Config must contain exactly one of [server] or [client] (or pass --server/--client)')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass --server or --client explicitly in scripts and systemd units","Keep separate config files for server and client roles","Validate section names against the rathole docs (watch for typos like [sever])"],"tags":["rust","configuration","run-mode","cli"],"backgroundTag":"missing-required-config-field","analyzedSha":"a292f7ed5402f840415fc6a53827da2f34337856","analyzedAt":"2026-09-07T09:56:55.739Z","contentChangedAt":"2026-09-07T09:56:55.739Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}