{"record":{"id":"ad4e29239e0b92d7","repo":"stamparm/maltrail","slug":"write-config","errorCode":null,"errorMessage":"write config","messagePattern":"write config","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/testkit.rs","lineNumber":127,"sourceCode":"             USE_CONDENSED_STORAGE false\\n\\\n             SENSOR_NAME harness\\n\\\n             SCAN_WINDOW 30\\n\\\n             USE_HEURISTICS {}\\n\\\n             CHECK_HOST_DOMAINS {}\\n\\\n             CHECK_MISSING_HOST {}\\n\\\n             LOG_DIR {}\\n\\\n             TRAILS_FILE {}\\n\",\n            options.use_heuristics,\n            options.check_host_domains,\n            options.check_missing_host,\n            log_dir.display(),\n            trails_file.display()\n        );\n        for line in &options.extra {\n            config_text.push_str(line);\n            config_text.push('\\n');\n        }\n        std::fs::write(&config_file, config_text).expect(\"write config\");\n\n        let mut cfg = Config::load(&config_file).expect(\"harness config must load\");\n        cfg.root = root.clone();\n        let cfg = Arc::new(cfg);\n\n        settings::init(root.clone());\n        crate::output::init_error_log(&log_dir, false);\n\n        // An empty whitelist keeps fixture trails from being filtered out; the shipped\n        // whitelist is exercised separately in tests/trails.rs. A test that sets USER_WHITELIST\n        // gets it honoured, so the precedence tests can pin real whitelist-vs-trail behaviour.\n        let whitelist = Arc::new(match cfg.user_whitelist.clone() {\n            Some(p) => Whitelist::load(&root, Some(&p)),\n            None => Whitelist::default(),\n        });\n\n        let db = build_db(trails);\n        let store = Arc::new(TrailStore::new(db));","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/testkit.rs#L109-L145","documentation":"with_options_in() renders the harness configuration (harness.conf) from a template plus options.extra lines and panics with \"write config\" if std::fs::write fails. This is the final filesystem setup step before Config::load, so a panic here means the harness environment could not be materialized at all.","triggerScenarios":"Calling Harness::write/with_options_in() when writing dir/harness.conf fails due to permissions, disk-full, a read-only filesystem, or the harness dir disappearing mid-setup (external temp cleaner, parallel test collision on the same pid).","commonSituations":"Disk-full CI machines; extra config lines in HarnessOptions::extra containing path separators or characters that make the rendered config invalid; concurrent harness instances colliding after a pid reuse in containers.","solutions":["Check temp-dir free space and permissions before running harness tests","Inspect options.extra lines for malformed config content and fix the caller-supplied options","Give each test run a dedicated TMPDIR to avoid cross-run temp collisions","Include the config path and io::Error in the panic message"],"exampleFix":"// before\nstd::fs::write(&config_file, config_text).expect(\"write config\");\n// after\nstd::fs::write(&config_file, &config_text)\n    .unwrap_or_else(|e| panic!(\"write config {}: {e}\\n--- config ---\\n{config_text}\", config_file.display()));","handlingStrategy":"validation","validationCode":"assert!(!options.extra.iter().any(|l| l.trim().is_empty() || l.contains('\\0')), \"invalid extra config line\");","typeGuard":null,"tryCatchPattern":"std::fs::write(&config_file, &config_text).unwrap_or_else(|e| panic!(\"write config {}: {e}\", config_file.display()));","preventionTips":["Validate HarnessOptions::extra lines before building the harness","Reserve temp-disk headroom in CI","Keep harness dir lifetimes contained to the test to avoid cross-run collisions"],"tags":["rust","filesystem","test-harness","config","file-write"],"backgroundTag":"file-write-failed","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"}