{"record":{"id":"7ef6122f8350778e","repo":"DioxusLabs/dioxus","slug":"failed-to-create-args-directory-for-rustc-wrapper","errorCode":null,"errorMessage":"Failed to create args directory for rustc wrapper","messagePattern":"Failed to create args directory for rustc wrapper","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/rustcwrapper.rs","lineNumber":110,"sourceCode":"\n    // Spawn the process and propagate its exit code.\n    let status = cmd.status().expect(\"Failed to execute rustc command\");\n    std::process::exit(status.code().unwrap_or(1)); // Exit with 1 if process was killed by signal\n}\n\nfn write_rustc_args(args_dir: &PathBuf, rustc_args: &RustcArgs) {\n    // Extract the crate name from the args to use as the filename.\n    // Skip non-sensical args when a build is completely fresh (rustc is invoked with --crate-name ___)\n    let crate_name = rustc_args\n        .args\n        .iter()\n        .skip_while(|arg| *arg != \"--crate-name\")\n        .nth(1);\n\n    if let Some(crate_name) = crate_name {\n        if crate_name != \"___\" {\n            std::fs::create_dir_all(args_dir)\n                .expect(\"Failed to create args directory for rustc wrapper\");\n\n            let crate_type = rustc_args\n                .args\n                .iter()\n                .skip_while(|arg| *arg != \"--crate-type\")\n                .nth(1)\n                .map(|s| s.as_str());\n\n            let serialized_args =\n                serde_json::to_string(rustc_args).expect(\"Failed to serialize rustc args\");\n\n            // Write args with an explicit target suffix: {crate_name}.lib.json or\n            // {crate_name}.bin.json. This avoids the ambiguity of a bare {crate_name}.json\n            // and ensures lib+bin crates don't overwrite each other.\n            let suffix = match crate_type {\n                Some(\"lib\" | \"rlib\") => \"lib\",\n                Some(\"bin\") => \"bin\",\n                _ => \"bin\", // proc-macro, cdylib, etc. — treat as bin","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/cli/src/rustcwrapper.rs#L92-L128","documentation":"The rustc wrapper persists every crate's rustc invocation as JSON files under an args directory; create_dir_all on that directory failed before writing. Typical causes are permissions, a read-only filesystem, or a stale root-owned target tree.","triggerScenarios":"dx build/dx serve where the dioxus rustc-args directory under target cannot be created: read-only mounts in CI/sandboxes, root-owned files from earlier sudo runs, or filesystem errors.","commonSituations":"Running `sudo dx build` once then building as a normal user; containerized builds over read-only volumes; antivirus/indexers locking target dirs on Windows.","solutions":["Fix ownership of the target directory: `sudo chown -R $(id -u):$(id -g) target`","Move CARGO_TARGET_DIR to a writable location or remount the volume read-write","Clean stale artifacts with `cargo clean` (or delete the dioxus args dir) and rebuild"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the target dir is creatable/writable before building\nfn target_writable(target_dir: &std::path::Path) -> bool {\n    let probe = target_dir.join(\".write-probe\");\n    std::fs::create_dir_all(target_dir).is_ok()\n        && std::fs::write(&probe, b\"\").is_ok()\n        && std::fs::remove_file(&probe).is_ok()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never mix sudo and normal-user dx builds in the same target dir","Check target dir ownership after any root-run build and chown it back","Point CARGO_TARGET_DIR at a writable location in containers/CI"],"tags":["cli","rustc-wrapper","filesystem","permissions","build"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}