{"record":{"id":"066bf7e3c69312e1","repo":"micro-editor/micro","slug":"error-s-is-a-directory-and-cannot-be-opened","errorCode":null,"errorMessage":"Error: %s is a directory and cannot be opened","messagePattern":"Error: (.+?) is a directory and cannot be opened","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/buffer/buffer.go","lineNumber":297,"sourceCode":"\t\tvar cursorPos []string\n\t\tfilename, cursorPos = util.GetPathAndCursorPosition(filename)\n\t\tcmd.StartCursor, err = ParseCursorLocation(cursorPos)\n\t\tif err != nil {\n\t\t\tcmd.StartCursor = Loc{-1, -1}\n\t\t}\n\t}\n\n\tfilename, err = util.ReplaceHome(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfileInfo, serr := os.Stat(filename)\n\tif serr != nil && !errors.Is(serr, fs.ErrNotExist) {\n\t\treturn nil, serr\n\t}\n\tif serr == nil && fileInfo.IsDir() {\n\t\treturn nil, errors.New(\"Error: \" + filename + \" is a directory and cannot be opened\")\n\t}\n\tif serr == nil && !fileInfo.Mode().IsRegular() {\n\t\treturn nil, errors.New(\"Error: \" + filename + \" is not a regular file and cannot be opened\")\n\t}\n\n\tf, err := os.OpenFile(filename, os.O_WRONLY, 0)\n\treadonly := errors.Is(err, fs.ErrPermission)\n\tf.Close()\n\n\tfile, err := os.Open(filename)\n\tif err == nil {\n\t\tdefer file.Close()\n\t}\n\n\tvar buf *Buffer\n\tif errors.Is(err, fs.ErrNotExist) {\n\t\t// File does not exist -- create an empty buffer with that name\n\t\tbuf = NewBufferFromString(\"\", filename, btype)","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/micro-editor/micro/blob/1c8b82b32e408a5faf340039ed92d5266bea3293/internal/buffer/buffer.go#L279-L315","documentation":"Returned by the buffer constructor path in internal/buffer/buffer.go:297 (NewBufferFromFile*) after os.Stat succeeds and the target is a directory. Micro buffers wrap regular file contents, so a directory cannot become a buffer and the open is refused before any read attempt. The path is included in the message.","triggerScenarios":"micro ~/projects on the command line; :open . inside a running session; a path that used to be a file but was replaced by a directory (deleted then mkdir'd) before open; a trailing-slash typo like 'micro src/'.","commonSituations":"Muscle-memory from terminal: running 'micro .' expecting a file tree (micro has none built in); scripts globbing paths that resolve to directories; symlink swapping during deploy.","solutions":["Pass a concrete file path: micro src/main.go instead of micro src","Inside micro use :open with an actual filename; use Tab-completion to land on files, not dirs","If you want directory navigation, install the filemanager plugin and open dirs through it","In code, stat and branch before calling NewBufferFromFile (see validation snippet)"],"exampleFix":"// before\nmicro ~/projects\n# Error: /home/u/projects is a directory and cannot be opened\n\n// after\nmicro ~/projects/main.go","handlingStrategy":"validation","validationCode":"// Pre-flight a path before buffer open\nfunc openBufferSafe(path string) (*buffer.Buffer, error) {\n    fi, err := os.Stat(path)\n    if err == nil && fi.IsDir() {\n        return nil, fmt.Errorf(\"%s is a directory — pass a file or use the filemanager plugin\", path)\n    }\n    return buffer.NewBufferFromFile(path, buffer.BTDefault)\n}","typeGuard":null,"tryCatchPattern":"buf, err := buffer.NewBufferFromFile(path, buffer.BTDefault)\nif err != nil {\n    if strings.HasSuffix(err.Error(), \"is a directory and cannot be opened\") {\n        // offer directory navigation instead of failing hard\n        InfoBar.Error(err)\n        return nil // non-fatal: user stays in current buffer\n    }\n    return nil, err\n}","preventionTips":["Shell out with a file glob completed path, not '.' or a bare folder","Use Tab completion on the command line so paths land on files","Install the filemanager plugin if you expect directory browsing"],"tags":["filesystem","path","open","buffer","io"],"backgroundTag":null,"analyzedSha":"1c8b82b32e408a5faf340039ed92d5266bea3293","analyzedAt":"2026-08-15T20:01:45.134Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}