{"record":{"id":"0fbc8b97387cfd7e","repo":"micro-editor/micro","slug":"error-s-is-not-a-regular-file-and-cannot-be-open","errorCode":null,"errorMessage":"Error: %s is not a regular file and cannot be opened","messagePattern":"Error: (.+?) is not a regular file and cannot be opened","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/buffer/buffer.go","lineNumber":300,"sourceCode":"\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)\n\t} else if err != nil {\n\t\treturn nil, err\n\t} else {","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/micro-editor/micro/blob/1c8b82b32e408a5faf340039ed92d5266bea3293/internal/buffer/buffer.go#L282-L318","documentation":"Returned by the same buffer constructor (internal/buffer/buffer.go:300) when os.Stat succeeds, the target is not a directory, but Mode().IsRegular() is false — i.e. character/block devices, FIFOs, Unix sockets and similar special files. Only regular files (or nonexistent paths, which create empty buffers) are openable; anything else is rejected with the path in the message.","triggerScenarios":"micro /dev/null, /dev/video0, /dev/tty, a named pipe created by mkfifo, or a unix socket file; :open /dev/urandom style probes.","commonSituations":"Trying to view device output in-editor ('micro /dev/ttyUSB0'); opening /dev/stdin or /dev/fd/N special files instead of piping (which micro supports via stdin: `cmd | micro`); container setups where a config path is a mounted socket.","solutions":["For stream-like sources, pipe instead: dmesg | micro (micro reads stdin when it's not a tty)","Open the backing regular file, not the device node","In code, require fi.Mode().IsRegular() before calling NewBufferFromFile (see validation snippet)"],"exampleFix":"// before\nmicro /dev/ttyUSB0\n# Error: /dev/ttyUSB0 is not a regular file and cannot be opened\n\n// after\ncat /dev/ttyUSB0 | micro","handlingStrategy":"validation","validationCode":"// Only regular files (or missing paths) reach NewBufferFromFile\nfunc isRegularOrMissing(path string) bool {\n    fi, err := os.Stat(path)\n    if err != nil { return true }                    // new buffer will be created\n    return fi.Mode().IsRegular()\n}\nif !isRegularOrMissing(p) { return fmt.Errorf(\"%s is a special file\", p) }","typeGuard":null,"tryCatchPattern":"buf, err := buffer.NewBufferFromFile(path, buffer.BTDefault)\nif err != nil {\n    if strings.HasSuffix(err.Error(), \"is not a regular file and cannot be opened\") {\n        // devices/fifos: redirect users to piping\n        InfoBar.Error(err.Error() + \" — pipe instead: cmd | micro\")\n        return nil\n    }\n    return nil, err\n}","preventionTips":["Use 'producer | micro' for streams instead of opening /dev nodes","For /proc and /sys views, copy to a temp file first","Audit scripts that feed globbed paths to micro so device entries are filtered"],"tags":["filesystem","path","open","special-files","buffer"],"backgroundTag":null,"analyzedSha":"1c8b82b32e408a5faf340039ed92d5266bea3293","analyzedAt":"2026-08-15T20:01:45.134Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}