{"record":{"id":"1007dcf23f637459","repo":"abiosoft/colima","slug":"failed-to-link-model-file-w","errorCode":null,"errorMessage":"failed to link model file: %w","messagePattern":"failed to link model file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"model/docker.go","lineNumber":91,"sourceCode":"\t\t\tif blobHash, ok := strings.CutPrefix(layer.Digest, \"sha256:\"); ok {\n\t\t\t\tblobPath = fmt.Sprintf(\"/models/blobs/sha256/%s\", blobHash)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif blobPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"no GGUF layer found in model manifest\")\n\t}\n\n\t// Create bundle directory and hard-link the blob (same approach as Docker Model Runner)\n\tbundleDir := fmt.Sprintf(\"/models/bundles/sha256/%s/model\", modelHash)\n\tif err := guest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"mkdir\", \"-p\", bundleDir); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create bundle directory: %w\", err)\n\t}\n\n\tif err := guest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"ln\", blobPath, bundlePath); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to link model file: %w\", err)\n\t}\n\n\treturn bundlePath, nil\n}\n\n// InspectDockerModel returns information about a Docker model.\nfunc InspectDockerModel(modelName string) (*DockerModelInfo, error) {\n\tguest := lima.New(host.New())\n\toutput, err := guest.RunOutput(\"docker\", \"model\", \"inspect\", modelName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error inspecting model %q: %w\", modelName, err)\n\t}\n\n\tvar info DockerModelInfo\n\tif err := json.Unmarshal([]byte(strings.TrimSpace(output)), &info); err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing model info: %w\", err)\n\t}\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/abiosoft/colima/blob/c3a5f9184d83a197184f897a9f07eb3c01b3bc88/model/docker.go#L73-L109","documentation":"findGGUFPath hard-links the blob into the bundle: guest.RunQuiet(\"docker\",\"exec\",\"docker-model-runner\",\"ln\",blobPath,bundlePath). ln (no -f) fails with EEXIST when a previous run already created the target file, ENOENT when the blob under /models/blobs/sha256/<hash> was garbage-collected, and EXDEV if blobs and bundles sit on different mounts.","triggerScenarios":"A leftover bundle file from an earlier failed serve (mkdir succeeded, ln failed, then retried); blob pruned by disk cleanup between manifest read and link; runner volume split so /models/blobs and /models/bundles are on different devices.","commonSituations":"Retrying after an interrupted first serve; disk cleanup tools pruning blobs; nonstandard runner volume configuration.","solutions":["Remove the stale target and retry: docker exec docker-model-runner rm -f <bundlePath> (or re-serve after cleanup)","Confirm the blob exists: docker exec docker-model-runner ls -l /models/blobs/sha256/<blobHash>; if missing, re-pull the model","Verify /models/blobs and /models/bundles live on the same volume (docker inspect ... .Mounts) so hard links are possible","Re-pull the model to restore a consistent blob+manifest+bundle set"],"exampleFix":"// before (fails with EEXIST on retry)\nguest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"ln\", blobPath, bundlePath)\n\n// after (idempotent link)\nguest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"sh\", \"-c\",\n    fmt.Sprintf(\"ln -f %q %q || (rm -f %q && ln %q %q)\", blobPath, bundlePath, bundlePath, blobPath, bundlePath))","handlingStrategy":"validation","validationCode":"// Make the link step idempotent: clear a stale target first.\nguest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"rm\", \"-f\", bundlePath)\n// ...then create the link","typeGuard":null,"tryCatchPattern":"if err := guest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"ln\", blobPath, bundlePath); err != nil {\n    // EEXIST from a stale bundle is the common retry-killer; remove and retry once\n    _ = guest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"rm\", \"-f\", bundlePath)\n    if err2 := guest.RunQuiet(\"docker\", \"exec\", \"docker-model-runner\", \"ln\", blobPath, bundlePath); err2 != nil {\n        return \"\", fmt.Errorf(\"failed to link model file: %w\", err2)\n    }\n}","preventionTips":["Treat bundle creation as idempotent: rm -f the target (or use ln -f) before linking","After a failed serve, clean /models/bundles/sha256/<hash> before retrying","Keep blobs and bundles on the same /models volume so hard links stay valid"],"tags":["docker","hardlink","model-runner","idempotency"],"backgroundTag":null,"analyzedSha":"c3a5f9184d83a197184f897a9f07eb3c01b3bc88","analyzedAt":"2026-08-15T18:58:08.334Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}