jdx/mise · error
push destination must be a fully-qualified reference (e.g. `
Error message
push destination must be a fully-qualified reference (e.g. `ghcr.io/you/devenv:tag`); got {:?} What it means
`mise oci push` requires the destination to be a fully-qualified OCI reference: registry host + repository path + optional tag/digest (e.g. `ghcr.io/you/devenv:tag`). Unlike docker/podman, mise has no implicit default registry (docker.io) to expand short names to, so it does an up-front `contains('/')` check and bails before building or uploading anything. The `{:?}` in the message is the raw reference string you passed.
Source
Thrown at src/cli/oci/push.rs:94
#[clap(long, value_name = "UID[:GID]")]
owner: Option<LayerOwner>,
/// Maintain the tag as a multi-arch image index
///
/// Pushes this build's manifest by digest and points the tag at an OCI
/// image index containing one entry per platform, preserving entries
/// other architectures pushed. Run `mise oci push --update-index` from
/// one runner per platform to assemble a multi-arch tag.
#[clap(long)]
update_index: bool,
}
impl Push {
pub async fn run(self) -> Result<()> {
Settings::get().ensure_experimental("mise oci push")?;
if !self.reference.contains('/') {
bail!(
"push destination must be a fully-qualified reference \
(e.g. `ghcr.io/you/devenv:tag`); got {:?}",
self.reference
);
}
// Keep the temp dir alive for the duration of the push — it removes
// itself on drop, so multi-hundred-megabyte image layouts don't
// accumulate in /tmp.
let mut reused_layers = 0;
let (image_dir, _tempdir_guard): (PathBuf, Option<TempDir>) =
if let Some(d) = &self.image_dir {
if !d.join("index.json").is_file() {
bail!(
"{}: does not look like an OCI image layout (missing index.json)",
d.display()
);
}
(d.clone(), None)View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Use a fully-qualified reference with registry host and namespace: `mise oci push ghcr.io/<you>/devenv:tag`
- For a local registry include the port: `mise oci push localhost:5000/devenv:tag`
- Check the variable your script feeds to push actually contains `registry/namespace/repo`
Example fix
# before mise oci push devenv:1.0 # after mise oci push ghcr.io/you/devenv:1.0
Defensive patterns
Strategy: validation
Validate before calling
# bash: require a slash before invoking push
ref="${1:?reference required}"
if [[ "$ref" != *"/"* ]]; then
echo "ref must be registry/namespace/repo[:tag]" >&2
exit 2
fi
mise oci push "$ref" Prevention
- Always store full references (registry+namespace+repo+tag) in CI variables; never compose them from a bare name
- Treat short names as invalid at the pipeline-config level (lint for refs without '/')
When it happens
Trigger: Running `mise oci push devenv:tag`, `mise oci push myimage`, or `mise oci push latest` — any destination string without at least one slash. Also scripts that assemble the reference from a short variable or a name without namespace.
Common situations: Muscle memory from `docker push name:tag` where the daemon silently injects docker.io; copying a repo short name from a browser URL (e.g. just `devenv`); CI variables that hold only the image name without registry/namespace.
Related errors
- --cache-from must reference the same repository as the desti
- fetching {manifest_url} failed: {}
- starting blob upload failed: {} {}{}
- blob chunk upload failed: {}{} {}
- blob upload failed: {}{} {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/111daabb20b88d24.
Report an issue: GitHub.