{"record":{"id":"c9b3bbec75ab8bf0","repo":"denoland/deno","slug":"is-owned-by-uid-not-current-uid","errorCode":null,"errorMessage":"'{}' is owned by uid {}, not current uid {}","messagePattern":"'(.+?)' is owned by uid (.+?), not current uid (.+?)","errorType":"exception","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/util/temp.rs","lineNumber":189,"sourceCode":"fn ensure_secure_temp_dir(path: &Path) -> Result<(), AnyError> {\n  use std::os::unix::fs::MetadataExt;\n  use std::os::unix::fs::OpenOptionsExt;\n  use std::os::unix::fs::PermissionsExt;\n\n  // Keep the check, permission repair, and final validation tied to the same\n  // directory so replacing the path cannot redirect the chmod. The canonical\n  // temp path and its ancestors are validated separately before subsequent\n  // path-based use.\n  let dir = std::fs::OpenOptions::new()\n    .read(true)\n    .custom_flags(libc::O_NOFOLLOW | libc::O_DIRECTORY)\n    .open(path)?;\n\n  // SAFETY: geteuid has no preconditions.\n  let current_uid = unsafe { libc::geteuid() };\n  let metadata = dir.metadata()?;\n  if metadata.uid() != current_uid {\n    bail!(\n      \"'{}' is owned by uid {}, not current uid {}\",\n      path.display(),\n      metadata.uid(),\n      current_uid\n    );\n  }\n\n  let mode = metadata.permissions().mode();\n  if mode & 0o077 != 0 {\n    dir.set_permissions(std::fs::Permissions::from_mode(0o700))?;\n  }\n\n  let metadata = dir.metadata()?;\n  if metadata.uid() != current_uid {\n    bail!(\n      \"'{}' is owned by uid {}, not current uid {}\",\n      path.display(),\n      metadata.uid(),","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/util/temp.rs#L171-L207","documentation":"`ensure_secure_temp_dir` guards the `deno_nm` temp root/day-folder itself: it opens the directory with O_NOFOLLOW|O_DIRECTORY and requires the owner to be exactly the current effective uid. Unlike the ancestor walk, root ownership (uid 0) is NOT accepted here, because Deno must fully trust and manage this folder's contents.","triggerScenarios":"Another account already created `<tmp>/deno_nm` (or the dated day folder under it) — a different user ran Deno first on a shared machine, you ran `sudo deno` after a user-level run (or vice versa), or a stale folder from an old uid remains after a uid change.","commonSituations":"Shared CI hosts where builds run as different service accounts with the same TMPDIR; sudo/user transitions; containers reusing a mounted /tmp volume across containers with different uids.","solutions":["Remove the foreign-owned folder: `sudo rm -rf /tmp/deno_nm` (it is a temp cache of node_modules; safe to delete).","Or chown it to the current user: `sudo chown -R $(id -u) /tmp/deno_nm`.","Give each user/container its own TMPDIR so they never collide on the same deno_nm path.","Re-run as the user who owns the existing folder if that is the intended account."],"exampleFix":"# before: /tmp/deno_nm was created by uid 1000, you are uid 1001\nls -ld /tmp/deno_nm     # drwx------ 1000 ...\ndeno install            # error: '/tmp/deno_nm' is owned by uid 1000, not current uid 1001\n\n# after\nsudo rm -rf /tmp/deno_nm\ndeno install","handlingStrategy":"validation","validationCode":"# detect a foreign-owned deno_nm before running deno\nd=\"${TMPDIR:-/tmp}/deno_nm\"\nif [ -e \"$d\" ] && [ \"$(stat -c %u \"$d\")\" != \"$(id -u)\" ]; then\n  echo \"deno_nm owned by uid $(stat -c %u \"$d\") — remove it or use a private TMPDIR\"\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give each user/service account its own TMPDIR on shared hosts.","Don't run deno alternately as root and as a user against the same temp root.","Don't mount one /tmp volume into containers with different uids."],"tags":["security","temp-dir","ownership","unix","shared-host"],"backgroundTag":"insecure-temp-directory","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}