{"record":{"id":"681b3b4e9c273ee3","repo":"jdx/mise","slug":"is-not-in-the-lockfile-hint-hint","errorCode":null,"errorMessage":"{}@{} is not in the lockfile\nhint: {hint}","messagePattern":"(.+?)@(.+?) is not in the lockfile\nhint: (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/toolset/tool_version.rs","lineNumber":391,"sourceCode":"            && let Some(lt) =\n                request.lockfile_resolve_with_prefix(config, lock_query, lock_prefix_boundary)?\n        {\n            return Ok(Self::from_lockfile(request.clone(), lt));\n        }\n        let settings = Settings::get();\n        let tool_config_locked = config.tool_config_locked(request.source());\n        if (settings.locked || tool_config_locked)\n            && opts.use_locked_version\n            && settings.lockfile_enabled()\n            && !has_linked_version(request.ba())\n            && request.source().path().is_some()\n        {\n            let hint = if tool_config_locked && !settings.locked {\n                \"Run `mise lock` to update the lockfile, or disable `tool_config.locked`\"\n            } else {\n                \"Run `mise install` without --locked to update the lockfile\"\n            };\n            bail!(\n                \"{}@{} is not in the lockfile\\nhint: {hint}\",\n                request.ba().short,\n                request.version()\n            );\n        }\n\n        match v.split_once(':') {\n            Some((ref_type @ (\"ref\" | \"tag\" | \"branch\" | \"rev\"), r)) => {\n                return Ok(Self::resolve_ref(\n                    r.to_string(),\n                    ref_type.to_string(),\n                    request.options(),\n                    &request,\n                ));\n            }\n            Some((\"path\", p)) => {\n                return Self::resolve_path(PathBuf::from(p), &request);\n            }","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/toolset/tool_version.rs#L373-L409","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `mise lock` locally and commit the updated mise.lock, then retry the locked install","If a one-time update is intended, run `mise install` without `--locked` (and without MISE_LOCKED)","If `tool_config.locked` was set accidentally, remove that setting from the tool's config block","Verify `lockfile` settings are not disabled so `mise lock` can actually write mise.lock"],"exampleFix":"# before\ngit clone repo && mise install --locked   # fails: mypath@path:./tools/x is not in the lockfile\n\n# after\nmise lock && git add mise.lock && git commit -m 'lock path tools'\nmise install --locked","handlingStrategy":"fallback","validationCode":"# CI: verify the lockfile covers every path: tool before a locked install\nmise lock --dry-run >/dev/null 2>&1 || true\ngrep -o 'path:[^\"]*' mise.toml | while read -r p; do\n  tool=$(echo \"$p\" | cut -d: -f1); grep -q \"^$tool\" mise.lock || { echo \"$tool missing from mise.lock\" >&2; exit 1; }\ndone\nmise install --locked","typeGuard":null,"tryCatchPattern":"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.","preventionTips":["Make `mise lock` part of the same commit/PR that adds or moves a path: tool","Commit mise.lock and treat lockfile drift in CI as a hard failure","Only enable tool_config.locked for tools whose lock entries you actively maintain"],"tags":["lockfile","locked-mode","path-tool","ci"],"backgroundTag":"lockfile-out-of-sync","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}