{"record":{"id":"04b48e8a418d1f29","repo":"lima-vm/lima","slug":"failed-to-open-asif-device-q-w","errorCode":null,"errorMessage":"failed to open ASIF device %#q: %w","messagePattern":"failed to open ASIF device %#q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/imgutil/nativeimgutil/asifutil/asif_darwin.go","lineNumber":53,"sourceCode":"}\n\n// NewAttachedASIF creates a new ASIF image file at the specified path with the given size\n// and attaches it, returning the attached device path and an open file handle.\n// The caller is responsible for detaching the ASIF image device when done.\nfunc NewAttachedASIF(path string, size int64) (string, *os.File, error) {\n\tif err := NewASIF(path, size); err != nil {\n\t\treturn \"\", nil, err\n\t}\n\tattachArgs := []string{\"image\", \"attach\", \"--noMount\", path}\n\tout, err := exec.CommandContext(context.Background(), \"diskutil\", attachArgs...).Output()\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"failed to attach ASIF image %#q: %w\", path, err)\n\t}\n\tdevicePath := strings.TrimSpace(string(out))\n\tf, err := os.OpenFile(devicePath, os.O_RDWR, 0o644)\n\tif err != nil {\n\t\t_ = DetachASIF(devicePath)\n\t\treturn \"\", nil, fmt.Errorf(\"failed to open ASIF device %#q: %w\", devicePath, err)\n\t}\n\treturn devicePath, f, err\n}\n\n// DetachASIF detaches the ASIF image device at the specified path.\nfunc DetachASIF(devicePath string) error {\n\tif output, err := exec.CommandContext(context.Background(), \"hdiutil\", \"detach\", devicePath).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"failed to detach ASIF image %#q: %w: %s\", devicePath, err, output)\n\t}\n\treturn nil\n}\n\n// ResizeASIF resizes the ASIF image at the specified path to the given size.\nfunc ResizeASIF(path string, size int64) error {\n\tresizeArgs := []string{\"image\", \"resize\", \"--size\", fmt.Sprintf(\"%d\", size), path}\n\tif output, err := exec.CommandContext(context.Background(), \"diskutil\", resizeArgs...).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"failed to resize ASIF image %#q: %w: %s\", path, err, output)\n\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/imgutil/nativeimgutil/asifutil/asif_darwin.go#L35-L71","documentation":"After attaching, NewAttachedASIF opens the reported device path with O_RDWR to use it as a raw disk. This error wraps the os.OpenFile failure on that device. Attach reported success, but the device node cannot be opened read/write.","triggerScenarios":"NewAttachedASIF gets a devicePath from diskutil output, but os.OpenFile fails: empty/incorrect device path parsed from output, permissions (process not permitted to open the disk device), or the device disappeared immediately after attach.","commonSituations":"Full Disk Access / permissions changes on newer macOS preventing access to /dev/disk*; output format change in diskutil causing a wrong trimmed path (e.g. with a newline suffix or BSD name instead of device node); sandboxed processes.","solutions":["Grant the terminal/process Full Disk Access so it can open raw disk devices","Inspect the parsed devicePath (log it) and verify it exists as a /dev node","Re-run manually: `diskutil image attach --noMount <path>` and compare output format","Run as a user with disk access or adjust sandbox/entitlements"],"exampleFix":"// before\ndevicePath, f, err := asifutil.NewAttachedASIF(path, size)\n// after\ndevicePath, f, err := asifutil.NewAttachedASIF(path, size)\nif err != nil && strings.Contains(err.Error(), \"failed to open ASIF device\") {\n    log.Printf(\"check Full Disk Access; device path parsing may need update\")\n}","handlingStrategy":"try-catch","validationCode":"// preflight: verify the process can open raw disk devices\nif _, err := os.OpenFile(\"/dev/disk0\", os.O_RDONLY, 0); err != nil { log.Printf(\"no raw disk access; grant Full Disk Access\") }","typeGuard":null,"tryCatchPattern":"device, f, err := asifutil.NewAttachedASIF(path, size)\nif err != nil && strings.Contains(err.Error(), \"failed to open ASIF device\") {\n    log.Printf(\"open failed for %q: check Full Disk Access / device path parsing\", device)\n    return err\n}","preventionTips":["Grant Full Disk Access to the terminal/app on modern macOS","Log devicePath returned by diskutil to catch output-format drift","Run Lima from a process with disk device permissions"],"tags":["macos","permissions","device-open","asif"],"backgroundTag":"disk-device-open-denied","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}