micro-editor/micro · error
Error: %s is a directory and cannot be opened
Error message
Error: %s is a directory and cannot be opened
What it means
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.
Source
Thrown at internal/buffer/buffer.go:297
var cursorPos []string
filename, cursorPos = util.GetPathAndCursorPosition(filename)
cmd.StartCursor, err = ParseCursorLocation(cursorPos)
if err != nil {
cmd.StartCursor = Loc{-1, -1}
}
}
filename, err = util.ReplaceHome(filename)
if err != nil {
return nil, err
}
fileInfo, serr := os.Stat(filename)
if serr != nil && !errors.Is(serr, fs.ErrNotExist) {
return nil, serr
}
if serr == nil && fileInfo.IsDir() {
return nil, errors.New("Error: " + filename + " is a directory and cannot be opened")
}
if serr == nil && !fileInfo.Mode().IsRegular() {
return nil, errors.New("Error: " + filename + " is not a regular file and cannot be opened")
}
f, err := os.OpenFile(filename, os.O_WRONLY, 0)
readonly := errors.Is(err, fs.ErrPermission)
f.Close()
file, err := os.Open(filename)
if err == nil {
defer file.Close()
}
var buf *Buffer
if errors.Is(err, fs.ErrNotExist) {
// File does not exist -- create an empty buffer with that name
buf = NewBufferFromString("", filename, btype)View on GitHub (pinned to 1c8b82b32e)
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)
Example fix
// before micro ~/projects # Error: /home/u/projects is a directory and cannot be opened // after micro ~/projects/main.go
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight a path before buffer open
func openBufferSafe(path string) (*buffer.Buffer, error) {
fi, err := os.Stat(path)
if err == nil && fi.IsDir() {
return nil, fmt.Errorf("%s is a directory — pass a file or use the filemanager plugin", path)
}
return buffer.NewBufferFromFile(path, buffer.BTDefault)
} Try / catch
buf, err := buffer.NewBufferFromFile(path, buffer.BTDefault)
if err != nil {
if strings.HasSuffix(err.Error(), "is a directory and cannot be opened") {
// offer directory navigation instead of failing hard
InfoBar.Error(err)
return nil // non-fatal: user stays in current buffer
}
return nil, err
} Prevention
- 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
When it happens
Trigger: 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/'.
Common situations: 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.
Related errors
- Error: %s is not a regular file and cannot be opened
- could not open file
- Error: %s is a directory and cannot be saved
- Error reading bindings.json file: %s
- Error: %s is not a regular file and cannot be saved
AI-assisted analysis of micro-editor/micro@1c8b82b32e (2026-08-15).
Data as JSON: /api/errors/066bf7e3c69312e1.
Report an issue: GitHub.