denoland/deno · error · AnyError

Invalid version passed ({}) Pass a semver, or a full 40 cha

Error message

Invalid version passed ({})

Pass a semver, or a full 40 character git commit hash, or a release channel name.

Usage:
{}

What it means

For non-canary upgrades, the passed version must parse as standard semver (`Version::parse_standard`) after stripping an optional leading `v`. This bail is the catch-all for malformed versions, showing the value and the usage text. Note this only checks format; whether the version exists is validated later when fetching.

Source

Thrown at cli/tools/upgrade.rs:1270

    let passed_version = passed_version
      .strip_prefix('v')
      .unwrap_or(&passed_version)
      .to_string();

    let (channel, passed_version) = if is_canary {
      if !re_hash.is_match(&passed_version) {
        bail!(
          "Invalid commit hash passed ({})\n\nPass a semver, or a full 40 character git commit hash, or a release channel name.\n\nUsage:\n{}",
          colors::gray(passed_version),
          UPGRADE_USAGE
        );
      }

      (ReleaseChannel::Canary, passed_version)
    } else {
      let Ok(semver) = Version::parse_standard(&passed_version) else {
        bail!(
          "Invalid version passed ({})\n\nPass a semver, or a full 40 character git commit hash, or a release channel name.\n\nUsage:\n{}",
          colors::gray(passed_version),
          UPGRADE_USAGE
        );
      };

      if semver.pre.contains(&SmallStackString::from_static("alpha")) {
        (ReleaseChannel::Alpha, passed_version)
      } else if semver.pre.contains(&SmallStackString::from_static("beta")) {
        (ReleaseChannel::Beta, passed_version)
      } else if semver.pre.contains(&SmallStackString::from_static("rc")) {
        (ReleaseChannel::Rc, passed_version)
      } else {
        (ReleaseChannel::Stable, passed_version)
      }
    };

    Ok(RequestedVersion::SpecificVersion(channel, passed_version))

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass a full semver, optionally with the `v` prefix: `deno upgrade v1.44.0`.
  2. For channels, use the channel flags/names rather than a version string.
  3. To just update, run `deno upgrade` with no argument (uses Latest for the channel).
  4. Verify the version exists on https://github.com/denoland/deno/releases before pinning it.

Example fix

# before
deno upgrade 1.44  # not full semver -> error

# after
deno upgrade v1.44.0
Defensive patterns

Strategy: validation

Validate before calling

# bash: loose semver pre-check (X.Y.Z with optional prerelease/build)
[[ "$VER" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-.+][0-9A-Za-z.-]+)?$ ]] || { echo "invalid semver"; exit 1; }
deno upgrade "$VER"

Type guard

is_semver() { [[ "$1" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-.+][0-9A-Za-z.-]+)?$ ]]; }

Try / catch

deno upgrade "$VER" 2>err.log || { grep -q 'Invalid version passed' err.log && echo "use X.Y.Z, a channel name, or no argument"; }

Prevention

When it happens

Trigger: `deno upgrade 1.2` (incomplete semver), `deno upgrade latest`, `deno upgrade 1.2.x`, or any string that fails semver parsing at cli/tools/upgrade.rs:1270 when not in canary mode.

Common situations: Typing `latest` or `stable` where a version is expected; copying tags like `v1.44.0-rc.1` incorrectly truncated; shell history edits leaving partial versions.

Related errors


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