jdx/mise · error

locked mode requires lockfile to be enabled hint: Remove…

Error message

locked mode requires lockfile to be enabled
hint: Remove `lockfile = false` or set `lockfile = true`, or disable locked mode

What it means

The `--locked` flag requires mise's lockfile feature to record and verify install URLs, but the setting `lockfile = false` disables that feature. The two are mutually exclusive, so mise fails early — before even the dry-run check — rather than silently performing an unlocked install.

Solutions

  1. Remove `lockfile = false` or set `lockfile = true` in settings
  2. Drop the --locked flag / locked=true setting if you don't want pinned installs
  3. Check for a conflicting MISE_LOCKFILE env var overriding the config

Example fix

// before (mise.toml)
[settings]
lockfile = false
// after
[settings]
lockfile = true
Defensive patterns

Strategy: validation

Validate before calling

// bash: refuse to pass --locked when lockfiles are disabled
[[ "$(mise settings get lockfile)" != "false" ]] || unset LOCKED_FLAG

Prevention

When it happens

Trigger: Running any install/lock operation with locked=true (CLI --locked or locked config) while `lockfile = false` is set in settings (mise.toml [settings], settings.toml, or MISE_LOCKFILE=false).

Common situations: CI script passes --locked but repo settings disable lockfiles; user previously disabled lockfiles to avoid lockfile churn and later adopted --locked.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/a513c8b6337dc9e9. Report an issue: GitHub.

Appendix: source

Thrown at src/backend/mod.rs:3368

            }
            if let Some(graph) = &tv.aube_lock {
                graph.warn_if_missing();
            }
            tv
        } else {
            self.prepare_install_version(&ctx, tv).await?
        };
        // Toolset installs preflight these options before doing any work, but
        // direct callers such as `install-into` must be protected here too.
        tv.request.ensure_safe_install_options()?;

        // Check for --locked mode: if enabled and no lockfile URL exists, fail early
        // Exempt tool stubs from lockfile requirements since they are ephemeral
        // Also exempt backends that don't support URL locking (e.g., Rust uses rustup)
        // This must run before the dry-run check so that --locked --dry-run still validates
        let settings = Settings::get();
        if ctx.locked && settings.lockfile == Some(false) {
            bail!(
                "locked mode requires lockfile to be enabled\n\
                hint: Remove `lockfile = false` or set `lockfile = true`, or disable locked mode"
            );
        }
        if ctx.locked && !tv.request.source().is_tool_stub() && self.supports_lockfile_url() {
            let platform_key = self.get_platform_key();
            let has_lockfile_url = tv
                .lock_platforms
                .get(&platform_key)
                .and_then(|p| p.url.as_ref())
                .is_some();
            if !has_lockfile_url {
                bail!(
                    "No lockfile URL found for {} on platform {} (--locked mode)\n\
                    hint: Run `mise lock` to generate lockfile URLs, or disable locked mode",
                    tv.style(),
                    platform_key
                );

View on GitHub (pinned to 533346cc37)