jdx/mise · error

TEMP is too long to replace mise.exe safely

Error message

TEMP is too long to replace mise.exe safely ({len} UTF-16 code units)

  TEMP = {tmp}

Updating moves the running mise.exe aside and then launches a helper from TEMP to
put the new one in place. That helper's path would be {helper} UTF-16 code units,
and Windows cannot launch an executable whose path reaches {max}. The move happens
first, so going ahead would leave no mise installed at all.

Point TEMP and TMP at a shorter directory and run mise self-update again:

  $env:TEMP = 'C:\Temp'; $env:TMP = 'C:\Temp'

What it means

On Windows, self-update moves the running mise.exe aside and launches a helper executable from the TEMP directory to complete the replacement. If the TEMP path is so long that the helper's full path would reach the MAX_PATH limit (32767 UTF-16 code units), Windows cannot launch it — and since the running binary was already moved, proceeding would leave no mise installed at all. mise checks this upfront and bails.

Solutions

  1. Set TEMP and TMP to a short directory: $env:TEMP = 'C:\Temp'; $env:TMP = 'C:\Temp', then rerun mise self-update
  2. Create C:\Temp if it does not exist
  3. Alternatively update via the install script instead of self-update

Example fix

// before
# TEMP=C:\Users\long.username\AppData\Local\Temp
mise self-update  # TEMP is too long to replace mise.exe safely
// after
$env:TEMP = 'C:\Temp'; $env:TMP = 'C:\Temp'
mise self-update
Defensive patterns

Strategy: validation

Validate before calling

if (("$(${#TEMP})" + 80 >= 32767)); then export TEMP='C:\Temp' TMP='C:\Temp'; fi; mise self-update

Prevention

When it happens

Trigger: Running `mise self-update` on Windows where the TEMP/TMP environment variable points to a deeply nested directory whose derived helper path length meets or exceeds MAX_PATH.

Common situations: Corporate machines with long user profile paths (C:\Users\very.long.username\AppData\Local\Temp); CI runners with deep temporary directories.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/cli/self_update.rs:495

        let msg = formatdoc! {r#"
            TEMP is too long to replace mise.exe safely ({len} UTF-16 code units)

              TEMP = {tmp}

            Updating moves the running mise.exe aside and then launches a helper from TEMP to
            put the new one in place. That helper's path would be {helper} UTF-16 code units,
            and Windows cannot launch an executable whose path reaches {max}. The move happens
            first, so going ahead would leave no mise installed at all.

            Point TEMP and TMP at a shorter directory and run mise self-update again:

              $env:TEMP = 'C:\Temp'; $env:TMP = 'C:\Temp'"#,
            len = tmp.as_os_str().encode_wide().count(),
            tmp = tmp.display(),
            helper = helper_path_len(&tmp, stem.as_deref()),
            max = MAX_PATH,
        };
        bail!("{msg}");
    }

    fn do_update(&self) -> Result<VersionStatus> {
        // Use block_in_place to allow self_update's blocking HTTP calls
        // to work within mise's async runtime
        tokio::task::block_in_place(|| self.do_update_blocking())
    }

    fn do_update_blocking(&self) -> Result<VersionStatus> {
        let settings = Settings::try_get();
        let source = settings
            .as_ref()
            .map(|settings| SelfUpdateSource::from_settings(settings))
            .unwrap_or_default();
        source.validate()?;
        let (repo_owner, repo_name) = source.repository_parts()?;
        let mut update = Update::configure();
        update.reqwest_client(Self::http_client()?);

View on GitHub (pinned to 533346cc37)