{"record":{"id":"3cf691f4216175ae","repo":"micro-editor/micro","slug":"error-creating-configuration-directory-s","errorCode":null,"errorMessage":"Error creating configuration directory: %s","messagePattern":"Error creating configuration directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/config/config.go","lineNumber":48,"sourceCode":"\n\t\tmicroHome = filepath.Join(xdgHome, \"micro\")\n\t}\n\tConfigDir = microHome\n\n\tif len(flagConfigDir) > 0 {\n\t\tif _, err := os.Stat(flagConfigDir); os.IsNotExist(err) {\n\t\t\te = errors.New(\"Error: \" + flagConfigDir + \" does not exist. Defaulting to \" + ConfigDir + \".\")\n\t\t} else {\n\t\t\tConfigDir = flagConfigDir\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Create micro config home directory if it does not exist\n\t// This creates parent directories and does nothing if it already exists\n\terr := os.MkdirAll(ConfigDir, os.ModePerm)\n\tif err != nil {\n\t\treturn errors.New(\"Error creating configuration directory: \" + err.Error())\n\t}\n\n\treturn e\n}\n","sourceCodeStart":30,"sourceCodeEnd":53,"githubUrl":"https://github.com/micro-editor/micro/blob/1c8b82b32e408a5faf340039ed92d5266bea3293/internal/config/config.go#L30-L53","documentation":"Returned by InitConfigDir when os.MkdirAll(ConfigDir, os.ModePerm) fails while creating the micro configuration directory (including parents). The wrapped error (commonly 'permission denied' or 'not a directory') explains why the chosen config path cannot be materialized.","triggerScenarios":"ConfigDir resolving into a read-only location (/etc/micro with non-root user), a path component existing as a regular file (mkdir fails with ENOTDIR), SELinux/AppArmor denial, or full disk. Fires at internal/config/config.go:48.","commonSituations":"Setting XDG_CONFIG_HOME to a path on a read-only mount, a leftover regular file named 'micro' inside the chosen config parent, containers with read-only rootfs, or disk quota exhaustion.","solutions":["Check the wrapped message: 'permission denied' -> fix ownership/perms (chown/chmod) on the parent path; 'not a directory' -> remove or rename the regular file blocking the path.","Point micro somewhere writable: export MICRO_CONFIG_HOME=/home/$USER/.micro-config or XDG_CONFIG_HOME=$HOME/.config.","On read-only-root containers, mount a writable volume over the config path.","Free disk space / raise quota if the write failed due to ENOSPC."],"exampleFix":"# before:\nXDG_CONFIG_HOME=/etc/xdg micro   # /etc/xdg/micro cannot be created -> error\n\n# after:\nexport XDG_CONFIG_HOME=$HOME/.config\nmicro","handlingStrategy":"fallback","validationCode":"func writableDirFor(path string) bool {\n    for p := path; ; p = filepath.Dir(p) {\n        if fi, err := os.Stat(p); err == nil {\n            return fi.IsDir() && p == path || fi.IsDir() // existing ancestor must be a dir\n        }\n        if p == \"/\" || p == \".\" {\n            return false\n        }\n    }\n}\n// simplified: check ancestors are dirs and the target is creatable (os.MkdirAll in a temp-clone test)","typeGuard":null,"tryCatchPattern":"if err := config.InitConfigDir(\"\"); err != nil {\n    if strings.HasPrefix(err.Error(), \"Error creating configuration directory\") {\n        // retry with a writable location: os.Setenv(\"MICRO_CONFIG_HOME\", \"/tmp/micro-cfg\")\n        _ = config.InitConfigDir(\"\")\n    }\n}","preventionTips":["Point XDG_CONFIG_HOME/MICRO_CONFIG_HOME at a location your user owns and can write.","Remove regular files that squat on a path component meant to be a directory (e.g. ~/.config/micro as a FILE).","On read-only filesystems, bind-mount or overlay a writable dir for the config path."],"tags":["config","filesystem","permissions","startup","mkdir"],"backgroundTag":null,"analyzedSha":"1c8b82b32e408a5faf340039ed92d5266bea3293","analyzedAt":"2026-08-15T20:01:45.134Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}