{"record":{"id":"598d16f4263d9ac0","repo":"BloopAI/vibe-kanban","slug":"failed-to-create-tracing-filter-598d16","errorCode":null,"errorMessage":"Failed to create tracing filter","messagePattern":"Failed to create tracing filter","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-app/src/main.rs","lineNumber":123,"sourceCode":"            .show()\n        {\n            tracing::warn!(\"Failed to send Tauri notification: {}\", e);\n        }\n    }\n}\n\nfn main() {\n    // Install rustls crypto provider before any TLS operations\n    rustls::crypto::aws_lc_rs::default_provider()\n        .install_default()\n        .expect(\"Failed to install rustls crypto provider\");\n\n    let log_level = std::env::var(\"RUST_LOG\").unwrap_or_else(|_| \"info\".to_string());\n    let filter_string = format!(\n        \"warn,server={level},services={level},db={level},executors={level},deployment={level},local_deployment={level},utils={level},vibe_kanban_tauri={level}\",\n        level = log_level\n    );\n    let env_filter = EnvFilter::try_new(filter_string).expect(\"Failed to create tracing filter\");\n\n    sentry_utils::init_once(SentrySource::Desktop);\n\n    tracing_subscriber::registry()\n        .with(tracing_subscriber::fmt::layer().with_filter(env_filter))\n        .with(sentry_layer())\n        .init();\n\n    // Shared token so we can tell the server to shut down when the app quits.\n    let shutdown_token = Arc::new(CancellationToken::new());\n    let shutdown_token_for_event = shutdown_token.clone();\n\n    // Holds downloaded update bytes until the app exits or user restarts.\n    // Created here (outside setup) so the RunEvent::Exit handler can access it.\n    let pending_update: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));\n    let pending_for_setup = pending_update.clone();\n    let pending_for_exit = pending_update.clone();\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/tauri-app/src/main.rs#L105-L141","documentation":"`tracing_subscriber::EnvFilter::try_new(filter_string)` returns Err when the filter directive string is not valid tracing filter syntax; the `.expect()` turns that into a panic at startup. Invalid syntax includes malformed directives, unknown level names (e.g. RUST_LOG set to \"verbose\"), stray commas/brackets, or invalid target=level pairs like \"server=\".","triggerScenarios":"Running the Tauri app with `RUST_LOG` set to a value that produces an invalid combined filter, e.g. RUST_LOG=\"trace,\" (trailing comma producing an empty directive is tolerated, but RUST_LOG=\"server=\" or \"=info\" or \"foo::bar=bogus\" fails), which gets interpolated into \"warn,server={level},...\".","commonSituations":"Users exporting RUST_LOG with IDE-style values (\"debugger\", \"5\"), typos like RUST_LOG=info,extra=, or level strings copied from other frameworks; shell profiles that set a malformed global RUST_LOG.","solutions":["Sanitize the RUST_LOG value before interpolation: only accept known levels (trace|debug|info|warn|error), else fall back to \"info\".","Replace expect with fallback: `EnvFilter::try_new(filter_string).unwrap_or_else(|_| EnvFilter::new(\"warn\"))` and log the parse failure.","Validate RUST_LOG at startup and print a clear message about the accepted format.","Test the filter with `RUST_LOG='warn,server=debug'` to confirm the accepted syntax."],"exampleFix":"// before\nlet log_level = std::env::var(\"RUST_LOG\").unwrap_or_else(|_| \"info\".to_string());\nlet env_filter = EnvFilter::try_new(filter_string).expect(\"Failed to create tracing filter\");\n// after\nlet log_level = match std::env::var(\"RUST_LOG\").as_deref() {\n    Ok(\"trace\") | Ok(\"debug\") | Ok(\"info\") | Ok(\"warn\") | Ok(\"error\") => std::env::var(\"RUST_LOG\").unwrap(),\n    _ => \"info\".to_string(),\n};\nlet env_filter = EnvFilter::try_new(filter_string)\n    .unwrap_or_else(|_| EnvFilter::new(\"warn\"));","handlingStrategy":"validation","validationCode":"// Only accept known level names from RUST_LOG\nconst LEVELS: [&str; 5] = [\"trace\", \"debug\", \"info\", \"warn\", \"error\"];\nlet level = std::env::var(\"RUST_LOG\").ok().filter(|v| LEVELS.contains(&v.as_str())).unwrap_or_else(|| \"info\".into());","typeGuard":"fn is_valid_log_level(s: &str) -> bool {\n    matches!(s, \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\")\n}","tryCatchPattern":"// Fall back instead of panicking:\nlet env_filter = EnvFilter::try_new(filter_string)\n    .unwrap_or_else(|e| {\n        eprintln!(\"Invalid RUST_LOG filter ({e}); using default\");\n        EnvFilter::new(\"warn,server=info\");\n    });","preventionTips":["Never interpolate raw RUST_LOG into filter strings without whitelisting.","Document the accepted RUST_LOG format in the app README.","Prefer EnvFilter::from_default_env() plus targeted directives over string formatting.","Add a startup smoke test that builds the filter for each accepted level."],"tags":["rust","tracing","logging","env-filter","configuration"],"backgroundTag":"invalid-log-filter-directive","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}