jdx/mise · error
{}: does not look like an OCI image layout (missing index.js
Error message
{}: does not look like an OCI image layout (missing index.json) What it means
When `--image-dir` is given, `mise oci push` treats the directory as a pre-existing OCI image layout to publish (it does NOT write the build output there — without the flag it builds into a temp dir). An OCI layout is identified by an `index.json` at its root; if that file is missing, mise refuses rather than guessing whether the dir is a partial or wrong-path layout.
Source
Thrown at src/cli/oci/push.rs:107
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)
} else {
let td = TempDir::with_prefix("mise-oci-push-")
.wrap_err("creating temp dir for oci build output")?;
let out_dir = td.path().join("image");
let opts = BuildOptions {
out_dir: out_dir.clone(),
from: self.from.clone(),
tag: Some(self.reference.clone()),
mount_point: self.mount_point.clone(),
owner: self.owner,
include_mise: !self.no_mise,
copy: vec![],
reuse_from: self.fetch_layer_cache().await?,View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Build a proper layout first: `mise oci build -o ./image ...`, then `mise oci push --image-dir ./image ghcr.io/...`
- Verify the marker file exists: `ls ./out/index.json` — it must be a file at the root of --image-dir
- Point --image-dir at the directory that directly contains index.json (and oci-layout/), not its parent or a subdirectory
Example fix
# before mise oci push --image-dir ./out ghcr.io/you/devenv:tag # ./out is empty # after mise oci build -o ./out && mise oci push --image-dir ./out ghcr.io/you/devenv:tag
Defensive patterns
Strategy: validation
Validate before calling
# bash: guard before push
image_dir="${1:?image dir required}"
if [ ! -f "$image_dir/index.json" ]; then
echo "$image_dir is not an OCI layout (no index.json); building..." >&2
mise oci build -o "$image_dir" || exit 1
fi
mise oci push --image-dir "$image_dir" dest:tag Prevention
- Treat index.json as the layout's contract marker and assert it in CI artifact steps
- Name build outputs explicitly (`mise oci build -o ./image`) and always pass that same root to --image-dir
When it happens
Trigger: `mise oci push --image-dir ./out ghcr.io/you/devenv:tag` where ./out has no index.json — e.g. an empty dir, the parent of the real layout, an interrupted build's leftovers, or a directory that only contains blobs/ but no index.json.
Common situations: Passing the directory you intended as build output instead of one produced by `mise oci build -o`; copying/extracting an artifact and dropping index.json; confusing the layout root with the surrounding project or temp dir.
Related errors
- {}: does not look like an OCI image layout (missing index.js
- {}: index.json lists no manifests
- {}: index.json lists {} manifests; multi-manifest layouts ar
- push destination must be a fully-qualified reference (e.g. `
- --cache-from must reference the same repository as the desti
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/ef8f4d4a5eae69e5.
Report an issue: GitHub.