abiosoft/colima · error

failed to parse model manifest: %w

Error message

failed to parse model manifest: %w

What it means

The manifest bytes read out of the runner container ('cat /models/manifests/sha256/<hash>') failed json.Unmarshal into ociManifest. The captured stdout was not valid JSON — typically because docker exec emitted a daemon error to stdout, the output was empty (container died mid-exec), or the manifest schema differs from the expected OCI layout.

Source

Thrown at model/docker.go:66

func findGGUFPath(guest environment.VM, modelHash string) (string, error) {
	// Standard bundle path used by Docker Model Runner for all models
	bundlePath := fmt.Sprintf("/models/bundles/sha256/%s/model/model.gguf", modelHash)

	// Check if bundle already exists
	if err := guest.RunQuiet("docker", "exec", "docker-model-runner", "test", "-f", bundlePath); err == nil {
		return bundlePath, nil
	}

	// Bundle doesn't exist - read manifest to find the GGUF blob and create the bundle
	manifestPath := fmt.Sprintf("/models/manifests/sha256/%s", modelHash)
	output, err := guest.RunOutput("docker", "exec", "docker-model-runner", "cat", manifestPath)
	if err != nil {
		return "", fmt.Errorf("failed to read model manifest: %w", err)
	}

	var manifest ociManifest
	if err := json.Unmarshal([]byte(output), &manifest); err != nil {
		return "", fmt.Errorf("failed to parse model manifest: %w", err)
	}

	// Find the GGUF layer (mediaType contains "gguf")
	var blobPath string
	for _, layer := range manifest.Layers {
		if strings.Contains(layer.MediaType, "gguf") {
			if blobHash, ok := strings.CutPrefix(layer.Digest, "sha256:"); ok {
				blobPath = fmt.Sprintf("/models/blobs/sha256/%s", blobHash)
				break
			}
		}
	}

	if blobPath == "" {
		return "", fmt.Errorf("no GGUF layer found in model manifest")
	}

	// Create bundle directory and hard-link the blob (same approach as Docker Model Runner)

View on GitHub (pinned to c3a5f9184d)

Solutions

  1. Run the failing command manually to see the raw output: colima ssh -- docker exec docker-model-runner cat /models/manifests/sha256/<hash>
  2. Confirm the runner container is stable: docker ps | grep docker-model-runner (no Restarting), restart it if needed
  3. Re-pull the model to regenerate the manifest
  4. On persistent parse failure, update Docker/Model Runner and colima so manifest writing and reading versions match

Example fix

// before
output, err := guest.RunOutput("docker", "exec", "docker-model-runner", "cat", manifestPath)
var manifest ociManifest
if err := json.Unmarshal([]byte(output), &manifest); err != nil {
    return "", fmt.Errorf("failed to parse model manifest: %w", err)
}

// after: surface the payload that failed to parse
output, err := guest.RunOutput("docker", "exec", "docker-model-runner", "cat", manifestPath)
var manifest ociManifest
if err := json.Unmarshal([]byte(output), &manifest); err != nil {
    return "", fmt.Errorf("failed to parse model manifest: %w (output: %.200q)", err, output)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-check on the payload before unmarshalling.
func looksLikeJSON(s string) bool {
    t := strings.TrimSpace(s)
    return strings.HasPrefix(t, "{") && strings.HasSuffix(t, "}")
}

Try / catch

var manifest ociManifest
if err := json.Unmarshal([]byte(output), &manifest); err != nil {
    // include the raw bytes: docker exec errors often arrive via stdout
    return "", fmt.Errorf("failed to parse model manifest: %w (raw: %.200q)", err, output)
}

Prevention

When it happens

Trigger: Runner container stopping between the test -f probe and the cat; docker CLI printing warnings/error text into stdout; an empty output when the manifest path exists but is a directory; upstream manifest format change (e.g. manifest lists) in a newer Model Runner.

Common situations: Flaky container lifecycle right after start; docker version mismatch between CLI in the VM and the runner container; truncated output on a slow VM.

Understand the failure class

Related errors


AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15). Data as JSON: /api/errors/170bb8064fa0d822. Report an issue: GitHub.