{"record":{"id":"7c3d7ec2cdd16a6d","repo":"denoland/deno","slug":"laufey-cache-dir-has-no-parent","errorCode":null,"errorMessage":"LAUFEY cache dir has no parent: {}","messagePattern":"LAUFEY cache dir has no parent: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":2000,"sourceCode":"      .await\n      .with_context(|| format!(\"failed to download {url}\"))?;\n    let data = response\n      .into_maybe_bytes()?\n      .ok_or_else(|| deno_core::anyhow::anyhow!(\"empty response from {url}\"))?;\n\n    let actual =\n      faster_hex::hex_string(&sha2::Sha256::digest(&data)).to_lowercase();\n    let expected_lc = expected.to_lowercase();\n    if actual != expected_lc {\n      // Include the URL in the bail: an attacker who poisoned a redirect\n      // would otherwise be invisible in the failure log.\n      bail!(\n        \"checksum mismatch for {archive} (downloaded from {url})\\n  expected: {expected_lc}\\n  actual:   {actual}\"\n      );\n    }\n\n    let parent = dir.parent().ok_or_else(|| {\n      deno_core::anyhow::anyhow!(\n        \"LAUFEY cache dir has no parent: {}\",\n        dir.display()\n      )\n    })?;\n    std::fs::create_dir_all(parent)?;\n\n    // Stage extraction in a sibling tempdir so concurrent `deno desktop`\n    // builds don't see (or stomp on) a half-populated `dir` while one\n    // is mid-extract. tempfile's cleanup-on-drop covers panic /\n    // early-return paths; on the happy path we consume the TempDir via\n    // `into_path` so the rename below sees a real directory.\n    let staging = tempfile::Builder::new()\n      .prefix(\".staging-\")\n      .tempdir_in(parent)\n      .with_context(|| {\n        format!(\"failed to stage tempdir in {}\", parent.display())\n      })?;\n","sourceCodeStart":1982,"sourceCodeEnd":2018,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L1982-L2018","documentation":"Before extracting the downloaded laufey archive, the code creates the parent of the target cache directory with fs::create_dir_all(parent). Path::parent() returns None only for paths with no parent component — the filesystem root '/' or a bare prefix like 'laufey:' on Windows — so this error signals a degenerate cache-directory path rather than a normal missing directory.","triggerScenarios":"The computed laufey cache dir resolves to '/' or another parentless path, which in practice requires a broken cache-root configuration (e.g. DENO_DIR or an equivalent cache env var set to '/' or to a Windows drive prefix) rather than anything the download itself can cause.","commonSituations":"An env var pointing the deno cache at the filesystem root; a container image where the cache dir was computed from an unset HOME that collapsed to a degenerate path; essentially never seen with a correctly configured environment.","solutions":["Check the cache-related environment variables (e.g. DENO_DIR) in the failing shell and make sure they point at a normal directory like ~/.cache/deno.","Unset the offending variable and let deno pick its default cache location.","If it persists with defaults, inspect how the cache path is derived for your platform and report it as a bug."],"exampleFix":"# before\nexport DENO_DIR=/          # cache dir collapses to a parentless path\n# error: LAUFEY cache dir has no parent: /\n\n# after\nunset DENO_DIR              # or: export DENO_DIR=\"$HOME/.cache/deno\"","handlingStrategy":"validation","validationCode":"# Validate the cache root before running: it must be a normal, parented directory\ncase \"${DENO_DIR:-$HOME/.cache/deno}\" in\n  /|\"\"|*[!/]/*/) ;;\n  *) test -d \"${DENO_DIR:-$HOME/.cache/deno}\" || echo \"cache dir missing (will be created)\" ;;\nesac\n# simplest guard: refuse degenerate values\ntest \"${DENO_DIR:-x}\" != \"/\" || { echo 'DENO_DIR must not be /'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never point DENO_DIR (or any cache env var) at the filesystem root.","In containers, ensure HOME is set so the default cache path resolves under a real directory.","Treat this error as a configuration smell: it cannot come from the network or the archive."],"tags":["filesystem","cache","env-var","path"],"backgroundTag":"path-has-no-parent-directory","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}