{"record":{"id":"2820400b973e79b8","repo":"stamparm/maltrail","slug":"must-load","errorCode":null,"errorMessage":"must load","messagePattern":"must load","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/config.rs","lineNumber":1323,"sourceCode":"    #[test]\n    fn several_remote_logging_endpoints_are_accepted_and_all_validated() {\n        let dir = std::env::temp_dir().join(\"mt-cfg-endpoints\");\n        let _ = std::fs::create_dir_all(&dir);\n        let base = \"MONITOR_INTERFACE any\\nCAPTURE_BUFFER 1MB\\nLOG_DIR /tmp\\nUPDATE_PERIOD 86400\\n\";\n        let write = |name: &str, extra: &str| {\n            let path = dir.join(name);\n            std::fs::write(&path, format!(\"{base}{extra}\")).unwrap();\n            Config::load(&path)\n        };\n\n        // one option, several collectors: comma, semicolon and whitespace all separate\n        let cfg = write(\"multi.conf\", \"SYSLOG_SERVER 1.2.3.4:514, 5.6.7.8:514\\n\").expect(\"must load\");\n        assert_eq!(split_endpoints(&cfg.syslog_server), vec![\"1.2.3.4:514\", \"5.6.7.8:514\"]);\n        let cfg = write(\"mixed.conf\", \"LOGSTASH_SERVER 1.2.3.4:5000;5.6.7.8:5000 9.9.9.9:5000\\n\").expect(\"must load\");\n        assert_eq!(split_endpoints(&cfg.logstash_server), vec![\"1.2.3.4:5000\", \"5.6.7.8:5000\", \"9.9.9.9:5000\"]);\n\n        // a single endpoint keeps behaving exactly as before\n        let cfg = write(\"one.conf\", \"SYSLOG_SERVER 1.2.3.4:514\\n\").expect(\"must load\");\n        assert_eq!(split_endpoints(&cfg.syslog_server), vec![\"1.2.3.4:514\"]);\n        assert!(split_endpoints(\"\").is_empty());\n\n        // EVERY endpoint is validated: a typo in the second is as fatal as one in the first,\n        // because forwarding to one of two configured collectors is silent half-failure.\n        assert!(write(\"bad2.conf\", \"SYSLOG_SERVER 1.2.3.4:514, nonsense\\n\").is_err());\n        assert!(write(\"bad1.conf\", \"SYSLOG_SERVER nonsense, 1.2.3.4:514\\n\").is_err());\n        assert!(write(\"badls.conf\", \"LOGSTASH_SERVER 1.2.3.4:5000, 5.6.7.8\\n\").is_err());\n    }\n\n    #[test]\n    fn worker_count_is_opt_in() {\n        let dir = std::env::temp_dir().join(\"mt-cfg-workers\");\n        let _ = std::fs::create_dir_all(&dir);\n        let base = \"MONITOR_INTERFACE any\\nCAPTURE_BUFFER 1MB\\nLOG_DIR /tmp\\nUPDATE_PERIOD 86400\\n\";\n\n        let write = |name: &str, extra: &str| {\n            let path = dir.join(name);","sourceCodeStart":1305,"sourceCodeEnd":1341,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/config.rs#L1305-L1341","documentation":"Not a runtime error but a test-side expect: the test helper `write()` builds a temp config file and calls Config::load, expecting success ('must load'). The expect fires only if Config::load rejects a config the test believes is valid, e.g. after an overly strict validation change. The declared 'cfg' here is the test closure's return value, not the production open_live path.","triggerScenarios":"Config::load returns Err for a config the test wrote (multi/mixed/one.conf with valid SYSLOG_SERVER/LOGSTASH_SERVER lines), typically after a new validation rule was added to Config::load.","commonSituations":"A developer adds endpoint or field validation to Config::load that unintentionally rejects previously-valid configs, breaking the unit tests that assert these files load.","solutions":["Run the failing test and read the underlying Config::load error message to see which key is rejected","Fix Config::load so valid multi-endpoint SYSLOG_SERVER/LOGSTASH_SERVER lines still parse, or correct the test fixture if it is genuinely invalid"],"exampleFix":"// before\nassert!(write(\"bad2.conf\", \"SYSLOG_SERVER 1.2.3.4:514, nonsense\\n\").is_ok());\n// after\nassert!(write(\"bad2.conf\", \"SYSLOG_SERVER 1.2.3.4:514, nonsense\\n\").is_err());","handlingStrategy":"try-catch","validationCode":"let cfg = Config::load(&path);\nassert!(cfg.is_ok(), \"config rejected: {:?}\", cfg.err());","typeGuard":null,"tryCatchPattern":"match Config::load(&path) {\n    Ok(cfg) => proceed(cfg),\n    Err(e) => eprintln!(\"config {} failed to load: {e}\", path.display()),\n}","preventionTips":["After adding validation rules, run the config unit tests before committing","Keep minimal fixtures covering every valid key combination","Log the underlying error, not just 'must load'"],"tags":["rust","tests","config"],"backgroundTag":"invalid-config-value","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}