jdx/mise · error · eyre::Report

{}@{} is not in the lockfile hint: {hint}

Error message

{}@{} is not in the lockfile
hint: {hint}

What it means

When mise runs in locked mode (the `--locked` flag / `MISE_LOCKED=1`, or `tool_config.locked = true` for the tool), it refuses to resolve a `path:`-backed tool request that has no matching entry in mise.lock. The lockfile is the source of truth for resolved state, and path tools must be explicitly recorded with `mise lock` before a locked install will proceed.

Source

Thrown at src/toolset/tool_version.rs:391

            && let Some(lt) =
                request.lockfile_resolve_with_prefix(config, lock_query, lock_prefix_boundary)?
        {
            return Ok(Self::from_lockfile(request.clone(), lt));
        }
        let settings = Settings::get();
        let tool_config_locked = config.tool_config_locked(request.source());
        if (settings.locked || tool_config_locked)
            && opts.use_locked_version
            && settings.lockfile_enabled()
            && !has_linked_version(request.ba())
            && request.source().path().is_some()
        {
            let hint = if tool_config_locked && !settings.locked {
                "Run `mise lock` to update the lockfile, or disable `tool_config.locked`"
            } else {
                "Run `mise install` without --locked to update the lockfile"
            };
            bail!(
                "{}@{} is not in the lockfile\nhint: {hint}",
                request.ba().short,
                request.version()
            );
        }

        match v.split_once(':') {
            Some((ref_type @ ("ref" | "tag" | "branch" | "rev"), r)) => {
                return Ok(Self::resolve_ref(
                    r.to_string(),
                    ref_type.to_string(),
                    request.options(),
                    &request,
                ));
            }
            Some(("path", p)) => {
                return Self::resolve_path(PathBuf::from(p), &request);
            }

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Run `mise lock` locally and commit the updated mise.lock, then retry the locked install
  2. If a one-time update is intended, run `mise install` without `--locked` (and without MISE_LOCKED)
  3. If `tool_config.locked` was set accidentally, remove that setting from the tool's config block
  4. Verify `lockfile` settings are not disabled so `mise lock` can actually write mise.lock

Example fix

# before
git clone repo && mise install --locked   # fails: mypath@path:./tools/x is not in the lockfile

# after
mise lock && git add mise.lock && git commit -m 'lock path tools'
mise install --locked
Defensive patterns

Strategy: fallback

Validate before calling

# CI: verify the lockfile covers every path: tool before a locked install
mise lock --dry-run >/dev/null 2>&1 || true
grep -o 'path:[^"]*' mise.toml | while read -r p; do
  tool=$(echo "$p" | cut -d: -f1); grep -q "^$tool" mise.lock || { echo "$tool missing from mise.lock" >&2; exit 1; }
done
mise install --locked

Try / catch

In scripts: if mise install --locked fails with 'is not in the lockfile', fall back to `mise lock && mise install --locked`, and fail the build if locking produces a diff you did not intend to commit.

Prevention

When it happens

Trigger: ToolVersion::resolve hits this when ALL of: settings.locked or tool_config.locked is set, opts.use_locked_version is true, lockfiles are enabled, the tool has no linked version, and the request source is a `path:` request — but mise.lock has no entry for that tool@version.

Common situations: Adding a new local/path-based tool (a fork at `path:./tools/foo`) to mise.toml and running `mise install --locked` in CI before running `mise lock`; a stale or uncommitted mise.lock after teammates changed path tools; enabling `tool_config.locked` on an existing tool that was never locked.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/681b3b4e9c273ee3. Report an issue: GitHub.