denoland/deno · error

deno ci requires a lockfile, but none was found. hint: run

Error message

deno ci requires a lockfile, but none was found.
  hint: run `deno install` to create one.

What it means

`deno ci` is the deterministic-install command: it reads deno.lock and installs exactly what the lockfile pins. It refuses to run when no lockfile exists, because there is nothing to verify against — the whole point of `ci` is lockfile-driven reproducibility.

Source

Thrown at cli/tools/installer/local.rs:203

  let npm_resolver = factory.npm_resolver().await?;
  print_install_report(
    &factory.sys(),
    start_instant.elapsed(),
    &install_reporter,
    workspace,
    npm_resolver,
  );

  Ok(())
}

pub async fn ci_command(
  flags: Arc<Flags>,
  ci_flags: CiFlags,
) -> Result<(), AnyError> {
  let factory = CliFactory::from_flags(flags.clone());
  if factory.maybe_lockfile().await?.is_none() {
    bail!(
      "deno ci requires a lockfile, but none was found.\n  hint: run `deno install` to create one."
    );
  }
  if let Some(node_modules_dir) = factory.node_modules_dir_path()?
    && node_modules_dir.exists()
  {
    log::info!(
      "{} {}",
      deno_terminal::colors::gray("Removing"),
      node_modules_dir.display()
    );
    std::fs::remove_dir_all(node_modules_dir).map_err(|err| {
      deno_core::anyhow::anyhow!(
        "failed to remove {}: {err}",
        node_modules_dir.display()
      )
    })?;
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Run `deno install` locally to generate/refresh deno.lock
  2. Commit deno.lock to the repository so `deno ci` has input in every environment
  3. Remove deno.lock from .gitignore if reproducible installs are wanted

Example fix

# before
deno ci   # deno ci requires a lockfile, but none was found.

# after
deno install   # creates deno.lock
git add deno.lock && git commit -m "chore: add lockfile"
deno ci
Defensive patterns

Strategy: validation

Validate before calling

# in CI, guarantee the lockfile exists before deno ci:
test -f deno.lock || { deno install; git add deno.lock; }
deno ci

Try / catch

On 'deno ci requires a lockfile': run `deno install` to generate it, commit it, then retry `deno ci` — a deterministic pipeline step.

Prevention

When it happens

Trigger: Running `deno ci` in a project where deno.lock has not been created yet — e.g. no `deno install` has ever run there, the lockfile is gitignored, or you are in a fresh clone of a repo that doesn't commit deno.lock.

Common situations: CI pipelines (GitHub Actions) on repos whose contributors never generated a lockfile; .gitignore entries that exclude deno.lock; fresh checkouts after adding new dependencies without running install.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f810817be8efabff. Report an issue: GitHub.