{"record":{"id":"65e426cec0e52555","repo":"micro-editor/micro","slug":"error-reading-settings-json-file-s","errorCode":null,"errorMessage":"Error reading settings.json file: %s","messagePattern":"Error reading settings\\.json file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/settings.go","lineNumber":247,"sourceCode":"\t\tif _, ok := defaults[k]; ok {\n\t\t\tif e := verifySetting(k, v, defaults[k]); e != nil {\n\t\t\t\terr = e\n\t\t\t\tparsedSettings[k] = defaults[k]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n\treturn err\n}\n\nfunc ReadSettings() error {\n\tparsedSettings = make(map[string]any)\n\tfilename := filepath.Join(ConfigDir, \"settings.json\")\n\tif _, e := os.Stat(filename); e == nil {\n\t\tinput, err := os.ReadFile(filename)\n\t\tif err != nil {\n\t\t\tsettingsParseError = true\n\t\t\treturn errors.New(\"Error reading settings.json file: \" + err.Error())\n\t\t}\n\t\tif !strings.HasPrefix(string(input), \"null\") {\n\t\t\t// Unmarshal the input into the parsed map\n\t\t\terr = json5.Unmarshal(input, &parsedSettings)\n\t\t\tif err != nil {\n\t\t\t\tsettingsParseError = true\n\t\t\t\treturn errors.New(\"Error reading settings.json: \" + err.Error())\n\t\t\t}\n\t\t\terr = validateParsedSettings()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ParsedSettings() map[string]any {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/micro-editor/micro/blob/1c8b82b32e408a5faf340039ed92d5266bea3293/internal/config/settings.go#L229-L265","documentation":"Returned by config.ReadSettings when settings.json exists (os.Stat succeeded) but os.ReadFile fails, so micro cannot even load the bytes. Sets settingsParseError = true, meaning later write-backs are suppressed to avoid clobbering the file. The wrapped error explains the I/O cause.","triggerScenarios":"settings.json with no read permission (mode 000 / different owner), the path being a directory named settings.json, or the file disappearing between Stat and ReadFile (race). Raised at internal/config/settings.go:247.","commonSituations":"Config dirs previously written by `sudo micro` leaving root-owned files, restore from backup with wrong permissions, or filesystem errors on network mounts.","solutions":["Fix ownership/permissions: sudo chown $USER:$USER ~/.config/micro/settings.json && chmod 644 ~/.config/micro/settings.json.","If the path is a directory, rename/remove it: rmdir or mv it away so micro can start fresh.","Check dmesg/mount logs if on a flaky network filesystem; remount and retry.","Because settingsParseError is set, fix the perms BEFORE making settings changes in-session or they will not persist."],"exampleFix":"# before:\nls -l ~/.config/micro/settings.json   # -rw------- root root\n# startup -> Error reading settings.json file: ... permission denied\n\n# after:\nsudo chown $USER:$USER ~/.config/micro/settings.json\nchmod 644 ~/.config/micro/settings.json","handlingStrategy":"validation","validationCode":"func readableSettingsFile(dir string) error {\n    p := filepath.Join(dir, \"settings.json\")\n    fi, err := os.Stat(p)\n    if err != nil {\n        return nil // absent file is fine\n    }\n    if fi.IsDir() {\n        return errors.New(\"settings.json is a directory\")\n    }\n    f, err := os.Open(p)\n    if err != nil {\n        return err // permission problem\n    }\n    f.Close()\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := config.ReadSettings(); err != nil {\n    if strings.HasPrefix(err.Error(), \"Error reading settings.json file:\") {\n        // I/O failure: fix perms before letting the user edit settings (parse error guard is set)\n    }\n}","preventionTips":["Never launch micro with sudo for daily editing; it creates root-owned config files.","After any restore/backup cycle, chown -R $USER ~/.config/micro.","Check permissions immediately if startup reports this, before changing settings in-session (writes are suppressed while settingsParseError is set)."],"tags":["settings","io","permissions","config","startup"],"backgroundTag":null,"analyzedSha":"1c8b82b32e408a5faf340039ed92d5266bea3293","analyzedAt":"2026-08-15T20:01:45.134Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}