jdx/mise · error

self_update.repository must be in owner/repository format…

Error message

self_update.repository must be in owner/repository format, got {:?}

What it means

The self-update configuration's `repository` field must be a plain `owner/repository` slug. `repository_parts` splits on a single '/' and validation additionally rejects empty owner/repo or extra slashes. This prevents constructing invalid GitHub API URLs during self-update.

Solutions

  1. Set self_update.repository to the `owner/repo` form, e.g. `jdx/mise`
  2. Remove any `https://github.com/` prefix or `.git` suffix from the value
  3. Check for leading/trailing slashes or double slashes in the setting
  4. Verify with the setting source (mise.toml, env var) that only the slug is configured

Example fix

// before
self_update.repository = "https://github.com/jdx/mise.git"
// after
self_update.repository = "jdx/mise"
Defensive patterns

Strategy: validation

Validate before calling

const repo = self_update_repository;
if (!/^[^/]+\/[^/]+$/.test(repo)) throw new Error(`repository must be owner/repo, got ${repo}`);

Try / catch

try {
  update_self()
} catch (e) {
  if (String(e).includes("owner/repository format")) {
    console.error("Fix self_update.repository to 'owner/repo', not a full URL");
  } else throw e;
}

Prevention

When it happens

Trigger: Setting the self_update.repository config (env/setting) to a value without a '/', with empty segments, or with nested paths like 'owner/org/repo'.

Common situations: Pasting a full GitHub URL instead of the slug, typos like '/owner/repo' or 'owner/', or pointing at a fork path with extra segments.

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


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

Appendix: source

Thrown at src/cli/version.rs:73

    }

    fn cache_path(&self) -> std::path::PathBuf {
        if self.is_default() {
            dirs::CACHE.join("latest-version")
        } else {
            dirs::CACHE.join(format!("latest-version-{}", crate::hash::hash_to_str(self)))
        }
    }

    #[cfg(feature = "self_update")]
    pub(crate) fn repository_parts(&self) -> Result<(&str, &str)> {
        let (owner, repo) = self.repository.split_once('/').ok_or_else(|| {
            eyre::eyre!(
                "self_update.repository must be in owner/repository format, got {:?}",
                self.repository
            )
        })?;
        eyre::ensure!(
            !owner.is_empty() && !repo.is_empty() && !repo.contains('/'),
            "self_update.repository must be in owner/repository format, got {:?}",
            self.repository
        );
        Ok((owner, repo))
    }

    pub(crate) fn validate(&self) -> Result<()> {
        let api_url = url::Url::parse(&self.api_url)?;
        eyre::ensure!(
            api_url.scheme() == "https",
            "self_update.api_url must use HTTPS, got {:?}",
            self.api_url
        );
        Ok(())
    }
}

View on GitHub (pinned to 533346cc37)