jdx/mise · error
invalid pinned revision
Error message
invalid pinned revision
What it means
install_at only accepts a full commit SHA: the revision must be exactly 40 (SHA-1) or 64 (SHA-256) ASCII hex characters. Anything else — branch names, tags, short SHAs, refs like HEAD — is rejected with this error before any network or filesystem work.
Solutions
- Resolve the full SHA first: `git rev-parse <ref>` on the source repo, then pass the 40- or 64-char result.
- If you only have a tag/branch, fetch the repository (Source::fetch) and resolve HEAD, or run `git ls-remote <origin> <ref>`.
- Check for stray whitespace or `origin/` prefixes in the revision string.
Example fix
// before
install_at("https://github.com/org/repo.git", "v1.2.0", ...).await?;
// after
let rev = "9fceb02d0ae598e95dc970b74767f19372d61af8"; // git ls-remote origin v1.2.0
install_at("https://github.com/org/repo.git", rev, ...).await?; Defensive patterns
Strategy: validation
Validate before calling
function isFullSha(rev: string): boolean {
return (rev.length === 40 || rev.length === 64) && /^[0-9a-fA-F]+$/.test(rev);
}
if (!isFullSha(revision)) throw new Error("resolve ref to full SHA first: git rev-parse <ref>"); Type guard
const isSha = (s: string): s is string => (s.length === 40 || s.length === 64) && /^[0-9a-f]{40}$|^[0-9a-f]{64}$/.test(s); Prevention
- Always resolve tags/branches to full SHAs (`git rev-parse` / `git ls-remote`) before install_at.
- Store full SHAs in config; trim whitespace programmatically.
- Never pass short SHAs or branch names.
When it happens
Trigger: Calling install / install_at / install_source / preview_source with revision values like `main`, `v1.2.3`, `abc123` (short SHA), or a SHA containing non-hex characters.
Common situations: Users passing a tag where a commit SHA is required; truncating a SHA when copying from CI logs; using a branch name assuming refs are supported.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- dotfile enrollment metadata must be a regular file
- Git remote helpers are not supported for remote onboarding
- invalid HTTP setup repository URL; use a Git credential…
- invalid repository origin
- invalid transferred repository bundle
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/c6747d6ff3981b87.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/remote_repository.rs:191
update,
yes,
dry_run,
&global_directory(),
)
}
fn install_at(
bundle: &Path,
origin: &str,
revision: &str,
update: bool,
yes: bool,
dry_run: bool,
destination: &Path,
) -> Result<PathBuf> {
validate_origin(origin)?;
if !matches!(revision.len(), 40 | 64) || !revision.bytes().all(|b| b.is_ascii_hexdigit()) {
bail!("invalid pinned revision");
}
if destination.is_symlink() {
bail!("global configuration directory must not be a symlink");
}
let parent = destination
.parent()
.ok_or_else(|| eyre::eyre!("missing parent directory"))?;
if !dry_run {
std::fs::create_dir_all(parent)?;
}
let _lock = crate::lock_file::LockFile::new(destination).lock()?;
// the checkout is renamed into place, so it is staged next to the
// destination; a dry run never renames and leaves the parent alone
let temporary = if dry_run {
tempfile::tempdir()?
} else {
tempfile::tempdir_in(parent)?
};View on GitHub (pinned to 533346cc37)