{"record":{"id":"78cea1e1f5651c78","repo":"jdx/mise","slug":"path-component-was-concurrently-created-by-anot","errorCode":null,"errorMessage":"path component {} was concurrently created by another user","messagePattern":"path component (.+?) was concurrently created by another user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":1672,"sourceCode":"                        });\n                    }\n                };\n                let created = openat(&directory, name.as_os_str(), flags, Mode::empty())\n                    .wrap_err_with(|| {\n                        format!(\n                            \"failed to open newly available path component {} without following symlinks\",\n                            component_path.display()\n                        )\n                    })?;\n                let stat = nix::sys::stat::fstat(&created)?;\n                if stat.st_uid != nix::unistd::geteuid().as_raw() {\n                    if created_by_us {\n                        bail!(\n                            \"created path component {} was replaced before it could be opened\",\n                            component_path.display()\n                        );\n                    } else {\n                        bail!(\n                            \"path component {} was concurrently created by another user\",\n                            component_path.display()\n                        );\n                    }\n                }\n                created\n            }\n        };\n        current.push(name);\n    }\n    Ok(directory)\n}\n\n#[cfg(unix)]\nfn set_directory_metadata(\n    directory: &std::os::fd::OwnedFd,\n    owner: Option<&str>,\n    group: Option<&str>,","sourceCodeStart":1654,"sourceCodeEnd":1690,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/managed_files.rs#L1654-L1690","documentation":"This error is raised by mise's managed-file bookkeeping when a path component that mise just created was found to already exist (or have different identity) by the time it was opened. If mise's own record shows it created that component, the file was swapped out from under it (replaced) before opening; if not, another user/process created it concurrently. It is a deliberate TOCTOU safety guard against symlink/race attacks on shared directories.","triggerScenarios":"Calling any managed-files API (create/write/remove helpers in src/system/managed_files.rs) that creates parent directories component-by-component while another process or user simultaneously creates the same component, or while something replaces the just-created directory with a symlink or file between creation and open.","commonSituations":"Two mise processes running concurrently against the same install dir (e.g. parallel CI jobs, two shells); a shared XDG cache/data directory on a multi-user machine where another user pre-creates the path; security software or sync tools (Dropbox, antivirus) replacing paths mid-operation.","solutions":["Re-run the command once the concurrent operation finishes; races are usually transient","Check ownership/permissions of the parent directory — if other users can write there, restrict it (chmod/others-writable dirs invite the race)","Ensure only one mise instance operates on the directory at a time (serialize CI jobs, avoid parallel task invocations touching the same paths)","Investigate what replaced the path (symlink planted by another user can indicate a security issue)"],"exampleFix":"// before: parallel jobs racing on the same mise data dir\n//   CI job A: mise install node  &  CI job B: mise install python &\n// after: serialize or lock\n//   flock /tmp/mise.lock -c 'mise install node && mise install python'","handlingStrategy":"retry","validationCode":"import { statSync, lstatSync } from \"node:fs\";\n// Before running concurrent mise operations on the same data dir, check the\n// path exists, is a real directory (not a symlink), and is owned by you:\nfunction isSafeManagedDir(p: string): boolean {\n  try {\n    const st = lstatSync(p);\n    return st.isDirectory() && st.uid === process.getuid?.();\n  } catch {\n    return true; // not created yet is fine\n  }\n}","typeGuard":"function isOwnedRealDir(p: string): boolean {\n  try {\n    const st = require(\"node:fs\").lstatSync(p);\n    return st.isDirectory() && !st.isSymbolicLink();\n  } catch { return false; }\n}","tryCatchPattern":"for (let attempt = 0; attempt < 3; attempt++) {\n  try {\n    await runMiseInstall();\n    break;\n  } catch (e) {\n    if (String(e).includes(\"concurrently created by another user\") && attempt < 2) {\n      await new Promise(r => setTimeout(r, 250 * (attempt + 1)));\n      continue;\n    }\n    throw e;\n  }\n}","preventionTips":["Serialize mise invocations that touch the same install/cache directories (flock, job queues)","Never share a mise data directory between users without restrictive permissions","Audit unexpected symlinks under the mise data dir — they trip this guard deliberately","Avoid file-sync tools (Dropbox/Drive) watching the mise data directory"],"tags":["filesystem","race-condition","concurrency","security"],"backgroundTag":"internal-invariant-violation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}