{"record":{"id":"3898e4f445564579","repo":"charmbracelet/glow","slug":"could-not-write-configuration-file-w","errorCode":null,"errorMessage":"could not write configuration file: %w","messagePattern":"could not write configuration file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config_cmd.go","lineNumber":60,"sourceCode":"\t\t\treturn fmt.Errorf(\"unable to set config file: %w\", err)\n\t\t}\n\t\tc.Stdin = os.Stdin\n\t\tc.Stdout = os.Stdout\n\t\tc.Stderr = os.Stderr\n\t\tif err := c.Run(); err != nil {\n\t\t\treturn fmt.Errorf(\"unable to run command: %w\", err)\n\t\t}\n\n\t\tfmt.Println(\"Wrote config file to:\", configFile)\n\t\treturn nil\n\t},\n}\n\nfunc ensureConfigFile() error {\n\tif configFile == \"\" {\n\t\tconfigFile = viper.GetViper().ConfigFileUsed()\n\t\tif err := os.MkdirAll(filepath.Dir(configFile), 0o755); err != nil { //nolint:gosec\n\t\t\treturn fmt.Errorf(\"could not write configuration file: %w\", err)\n\t\t}\n\t}\n\n\tif ext := path.Ext(configFile); ext != \".yaml\" && ext != \".yml\" {\n\t\treturn fmt.Errorf(\"'%s' is not a supported configuration type: use '%s' or '%s'\", ext, \".yaml\", \".yml\")\n\t}\n\n\tif _, err := os.Stat(configFile); errors.Is(err, fs.ErrNotExist) {\n\t\t// File doesn't exist yet, create all necessary directories and\n\t\t// write the default config file\n\t\tif err := os.MkdirAll(filepath.Dir(configFile), 0o700); err != nil {\n\t\t\treturn fmt.Errorf(\"unable create directory: %w\", err)\n\t\t}\n\n\t\tf, err := os.Create(configFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to create config file: %w\", err)\n\t\t}","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/charmbracelet/glow/blob/e3970c813d93da1ea84edfca90c289d9afb82242/config_cmd.go#L42-L78","documentation":"ensureConfigFile, when --config was not passed, takes configFile from viper.GetViper().ConfigFileUsed() and immediately does os.MkdirAll(filepath.Dir(configFile), 0o755) to make sure the parent directory exists. This error wraps that MkdirAll failure. It fires before extension checks or file creation, so it is about the directory, not the file.","triggerScenarios":"The resolved config directory cannot be created or written: permission denied on an existing parent (e.g. ~/.config owned by root); the path component exists as a regular file; read-only filesystem or full disk; XDG_CONFIG_HOME pointing somewhere unwritable; ConfigFileUsed() returning an empty/unexpected value so Dir() resolves oddly.","commonSituations":"Running glow as a different user than the home owner after files were created with sudo; containers with a read-only /root; HOME unset so the config path collapses; disk quota exhausted.","solutions":["Check ownership and permissions of the config dir: ls -ld ~/.config ~/.config/glow","Take ownership: sudo chown -R $USER ~/.config","Point elsewhere: glow config --config /tmp/glow.yml (on a writable path)","Verify XDG_CONFIG_HOME/HOME are set to writable locations"],"exampleFix":"# before\n$ glow config\n# Error: could not write configuration file: mkdir /home/user/.config/glow: permission denied\n\n# after\n$ sudo chown -R \"$USER\" ~/.config && glow config","handlingStrategy":"validation","validationCode":"func ensureConfigDirWritable(cfgPath string) error {\n\tdir := filepath.Dir(cfgPath)\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"config dir %s unusable: %w\", dir, err)\n\t}\n\tif !isWritable(dir) {\n\t\treturn fmt.Errorf(\"config dir %s is not writable by uid %d\", dir, os.Getuid())\n\t}\n\treturn nil\n}\n\nfunc isWritable(dir string) bool {\n\tf, err := os.CreateTemp(dir, \".glow-probe-*\")\n\tif err != nil {\n\t\treturn false\n\t}\n\t_ = f.Close()\n\t_ = os.Remove(f.Name())\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"if err := ensureConfigFile(); err != nil {\n\tif strings.Contains(err.Error(), \"could not write configuration file\") {\n\t\t// directory-level failure: report ownership hint instead of retrying blindly\n\t\tfmt.Fprintf(os.Stderr, \"fix perms on %s (chown -R $USER) or pass --config elsewhere\\n\", filepath.Dir(configFile))\n\t\tos.Exit(1)\n\t}\n\treturn err\n}","preventionTips":["Never create glow's config directory with sudo if glow runs as your user","Set XDG_CONFIG_HOME only to paths your user owns and can write","Probe writability with os.CreateTemp in the config dir before first run in automation"],"tags":["config","filesystem","permissions","mkdir"],"backgroundTag":null,"analyzedSha":"e3970c813d93da1ea84edfca90c289d9afb82242","analyzedAt":"2026-08-15T22:50:54.304Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}