jdx/mise · error
repos: {}: {reason}
Error message
repos: {}: {reason} What it means
preflight_statuses rejects RepoState::Conflict entries, whose reason string comes from status_one: (1) `path exists and is not a directory` — a file occupies the target path; (2) `path exists and is not a git repository` — a non-empty directory with no .git; (3) `origin does not match configured url` — the clone's origin identifies a different repository than the configured url. Origin comparison is transport-agnostic: `git@host:path`, `ssh://git@host/path`, and `https://host/path` are equivalent, but a different host, owner/path, non-`git` ssh user, explicit port, or insecure `http://`/`git://` is a conflict.
Source
Thrown at src/system/repos.rs:167
write!(f, "{}", file::display_path(&self.path))
}
}
pub fn status(requests: &[RepoRequest]) -> Result<Vec<RepoStatus>> {
requests.iter().map(status_one).collect()
}
pub fn preflight_statuses(statuses: &[RepoStatus]) -> Result<()> {
for status in statuses {
match &status.state {
RepoState::Dirty => {
bail!(
"repos: {} has local changes; commit, stash, or clean them before bootstrap",
status.request
);
}
RepoState::Conflict(reason) => {
bail!("repos: {}: {reason}", status.request);
}
RepoState::Current | RepoState::Missing | RepoState::Differs => {}
}
}
Ok(())
}
/// Apply statuses previously validated with [`preflight_statuses`].
pub(crate) fn apply_statuses(statuses: &[RepoStatus], dry_run: bool) -> Result<()> {
for status in statuses {
match &status.state {
RepoState::Current => {
info!("repos: {} already current", status.request);
}
RepoState::Missing => clone_repo(&status.request, dry_run)?,
RepoState::Differs => update_repo(&status.request, dry_run)?,
RepoState::Dirty | RepoState::Conflict(_) => unreachable!("preflighted above"),
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- For a non-directory or non-git path: move or delete it (`mv ~/src/x ~/src/x.bak`) so bootstrap can clone fresh
- For an origin mismatch: point the remote at the configured URL with `git -C <repo> remote set-url origin <configured-url>`, or update the config url to the URL you actually use
- Keep owner/path identical across transports — `https://github.com/o/r` matches `git@github.com:o/r.git`, but not `git@gitlab.com:o/r.git` or `ssh://git@github.com:2222/o/r.git`
Example fix
# before: origin conflict $ git -C ~/src/mise remote set-url origin https://github.com/other/mise.git # after: align the remote with the configured url $ git -C ~/src/mise remote set-url origin https://github.com/jdx/mise.git $ mise bootstrap
Defensive patterns
Strategy: validation
Validate before calling
fn origin_matches(path: &Path, configured_url: &str) -> bool {
let out = std::process::Command::new("git")
.arg("-C").arg(path)
.args(["config", "--get", "remote.origin.url"])
.output();
matches!(out, Ok(o) if o.status.success() && String::from_utf8_lossy(&o.stdout).trim() == configured_url)
}
// treat the repo as manageable only when the path is a directory containing .git
// and the origin matches (ssh/https equivalents of the same host/path are accepted by mise). Type guard
fn path_is_clonable_target(path: &Path) -> bool {
!path.exists() || (path.is_dir() && path.join(".git").exists())
} Prevention
- After forking or moving a remote, run `git remote set-url origin <url-from-config>` in the clone
- Avoid ssh host aliases and explicit ports in origins when config uses the canonical URL (or mirror it exactly)
- Remember `http://`, `git://`, userless ssh, and query-string URLs are never treated as equivalent to the configured https/ssh form
When it happens
Trigger: A regular file already exists at the repo path; the directory was pre-created with content but no .git; the clone's origin points at a fork, a different host, an ssh alias (`git@github-work:...`), an explicit port, or a userless ssh form while config declares an explicit-user/https URL.
Common situations: Re-cloning a project after forking while config still names upstream; ssh host aliases in ~/.ssh/config vs literal hosts in mise.toml; switching between ssh and https forms of the same repo is fine, switching host or owner is not.
Related errors
- repos: {} has local changes; commit, stash, or clean them be
- git -C {} {} failed: {}
- git failed with status {status}
- no configured repo matched path: {filter}
- relative repo paths are only allowed in a project config; us
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/f1c0d16f9f5a4d1b.
Report an issue: GitHub.