{"record":{"id":"433368dfbcc44c71","repo":"denoland/deno","slug":"no-lockfile-found-run-deno-install-first","errorCode":null,"errorMessage":"No lockfile found. Run `deno install` first.","messagePattern":"No lockfile found\\. Run `deno install` first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/pm/why.rs","lineNumber":65,"sourceCode":"/// The string portion is the lockfile's key:\n/// - npm: e.g. \"express@4.22.1\" or \"react-dom@18.2.0_react@18.2.0\"\n/// - jsr: e.g. \"@std/async@1.2.0\"\ntype PkgId = (PackageKind, String);\n\nfn display_base(id: &PkgId) -> &str {\n  match id.0 {\n    PackageKind::Npm => strip_peer_suffix(&id.1),\n    PackageKind::Jsr => &id.1,\n  }\n}\n\npub async fn why(\n  flags: Arc<Flags>,\n  why_flags: WhyFlags,\n) -> Result<(), AnyError> {\n  let factory = CliFactory::from_flags(flags);\n  let lockfile = factory.maybe_lockfile().await?.cloned().ok_or_else(|| {\n    deno_core::anyhow::anyhow!(\"No lockfile found. Run `deno install` first.\")\n  })?;\n\n  // Workspace-declared root dependency requirements (from deno.json `imports`,\n  // `scopes`, `jsxImportSource`, etc., and from package.json\n  // `dependencies`/`devDependencies`). These are matched against the lockfile's\n  // `specifiers` map to decide which entries are user-imported roots vs.\n  // transitive resolutions that the lockfile also stores under `specifiers`\n  // (as JSR does for every dep req).\n  let workspace = factory.cli_options()?.workspace();\n  let mut root_reqs: HashSet<JsrDepPackageReq> = HashSet::new();\n  for deno_json in workspace.deno_jsons() {\n    root_reqs.extend(deno_json.dependencies(workspace.catalogs()));\n  }\n  for pkg_json in workspace.package_jsons() {\n    let deps = pkg_json.resolve_local_package_json_deps();\n    for dep in deps\n      .dependencies\n      .values()","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/tools/pm/why.rs#L47-L83","documentation":"`deno why` explains why a package is in the dependency graph by walking the lockfile (deno.lock). It hard-requires a lockfile; without one there are no resolutions to explain, hence the pointer to `deno install`.","triggerScenarios":"`deno why <pkg>` in a project that never ran `deno install`, with deno.lock deleted, or with the lockfile disabled (--no-lock or lockfile disabled in config).","commonSituations":"Fresh clones where install was skipped; CI jobs disabling the lockfile for speed; lockfiles gitignored or removed during cleanup.","solutions":["Run `deno install` to generate deno.lock, then retry deno why","Make sure you are in the workspace directory the lockfile belongs to","Remove --no-lock / re-enable the lockfile if you want deno why to work","Restore deno.lock from version control if it was deleted"],"exampleFix":"# before\n$ deno why chalk\nError: No lockfile found. Run `deno install` first.\n# after\n$ deno install && deno why chalk","handlingStrategy":"validation","validationCode":"test -f deno.lock || { echo 'no lockfile — run deno install first' >&2; exit 2; }\ndeno why \"$1\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Commit deno.lock to version control","Make `deno install` an explicit prerequisite step in docs and CI before any deno why usage"],"tags":["pm","why","lockfile","dependencies"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}