{"record":{"id":"50fd33db3ef25497","repo":"kovidgoyal/kitty","slug":"failed-to-create-config-directory-to-store-favorit","errorCode":null,"errorMessage":"Failed to create config directory to store favorites in: %w","messagePattern":"Failed to create config directory to store favorites in: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/unicode_input/main.go","lineNumber":445,"sourceCode":"\nfunc (self *handler) handle_emoticons_key_event(event *loop.KeyEvent) {\n}\n\nfunc (self *handler) handle_favorites_key_event(event *loop.KeyEvent) {\n\tif event.MatchesPressOrRepeat(\"f12\") {\n\t\tevent.Handled = true\n\t\texe, err := os.Executable()\n\t\tif err != nil {\n\t\t\tself.err = err\n\t\t\tself.lp.Quit(1)\n\t\t\treturn\n\t\t}\n\t\tfp := favorites_path()\n\t\tif len(load_favorites(false)) == 0 || !favorites_loaded_from_user_config {\n\t\t\traw := serialize_favorites(load_favorites(false))\n\t\t\terr = os.MkdirAll(filepath.Dir(fp), 0o755)\n\t\t\tif err != nil {\n\t\t\t\tself.err = fmt.Errorf(\"Failed to create config directory to store favorites in: %w\", err)\n\t\t\t\tself.lp.Quit(1)\n\t\t\t\treturn\n\t\t\t}\n\t\t\terr = utils.AtomicUpdateFile(fp, bytes.NewReader(utils.UnsafeStringToBytes(raw)), 0o600)\n\t\t\tif err != nil {\n\t\t\t\tself.err = fmt.Errorf(\"Failed to write to favorites file %s with error: %w\", fp, err)\n\t\t\t\tself.lp.Quit(1)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\terr = self.lp.SuspendAndRun(func() error {\n\t\t\tcmd := exec.Command(exe, \"edit-in-kitty\", \"--type=overlay\", fp)\n\t\t\tcmd.Stdin = os.Stdin\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Stderr = os.Stderr\n\t\t\terr = cmd.Run()\n\t\t\tif err == nil {\n\t\t\t\tload_favorites(true)","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/unicode_input/main.go#L427-L463","documentation":"The unicode_input kitten stores your favorites (recently used characters) in a JSON file under the kitty config directory. Before writing, it creates the parent directory with os.MkdirAll; if creation fails (permission denied, read-only filesystem, a file exists where the directory should be), handle_favorites_key_event records this error and quits the kitten with exit code 1.","triggerScenarios":"Pressing the favorites key (default f) in the unicode input kitten when ~/.config/kitty (or XDG_CONFIG_HOME equivalent) cannot be created — unwritable HOME, sandboxed environment, or a regular file occupying the config directory path.","commonSituations":"Running kitty/kitten in a container or sandbox with a read-only $HOME; wrong ownership of ~/.config after running with sudo; XDG_CONFIG_HOME pointing to an invalid path.","solutions":["Check permissions on the config dir: mkdir -p ~/.config/kitty && chown -R $USER ~/.config","Verify XDG_CONFIG_HOME (if set) points to a writable directory","Remove any regular file blocking the directory path (e.g. a file named ~/.config/kitty)","If sandboxed, grant write access to the config directory or unset favorites-related flows"],"exampleFix":"# before\n$ ls -la ~/.config/kitty\n-rw-r--r-- 1 root root /home/user/.config/kitty\n\n# after\n$ rm ~/.config/kitty\n$ mkdir -p ~/.config/kitty && chown $USER ~/.config/kitty","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(favorites_path())\nif info, err := os.Stat(dir); err == nil && !info.IsDir() {\n    return fmt.Errorf(\"%s exists but is not a directory\", dir)\n}\nif err := os.MkdirAll(dir, 0o755); err != nil {\n    return fmt.Errorf(\"cannot create %s: %w\", dir, err)\n}","typeGuard":null,"tryCatchPattern":"if err := os.MkdirAll(filepath.Dir(fp), 0o755); err != nil {\n    log.Printf(\"skipping favorites save, config dir unwritable: %v\", err)\n    // continue without persisting favorites\n}","preventionTips":["Keep ~/.config owned by your user; avoid running kitty under sudo","Set XDG_CONFIG_HOME to a writable location in sandboxes","Pre-create kitty config dirs in container images"],"tags":["kitty","unicode-input","filesystem","permissions","config"],"backgroundTag":"config-directory-not-writable","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}