micro-editor/micro · error

Error reading settings.json file: %s

Error message

Error reading settings.json file: %s

What it means

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.

Source

Thrown at internal/config/settings.go:247

		if _, ok := defaults[k]; ok {
			if e := verifySetting(k, v, defaults[k]); e != nil {
				err = e
				parsedSettings[k] = defaults[k]
				continue
			}
		}
	}
	return err
}

func ReadSettings() error {
	parsedSettings = make(map[string]any)
	filename := filepath.Join(ConfigDir, "settings.json")
	if _, e := os.Stat(filename); e == nil {
		input, err := os.ReadFile(filename)
		if err != nil {
			settingsParseError = true
			return errors.New("Error reading settings.json file: " + err.Error())
		}
		if !strings.HasPrefix(string(input), "null") {
			// Unmarshal the input into the parsed map
			err = json5.Unmarshal(input, &parsedSettings)
			if err != nil {
				settingsParseError = true
				return errors.New("Error reading settings.json: " + err.Error())
			}
			err = validateParsedSettings()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func ParsedSettings() map[string]any {

View on GitHub (pinned to 1c8b82b32e)

Solutions

  1. Fix ownership/permissions: sudo chown $USER:$USER ~/.config/micro/settings.json && chmod 644 ~/.config/micro/settings.json.
  2. If the path is a directory, rename/remove it: rmdir or mv it away so micro can start fresh.
  3. Check dmesg/mount logs if on a flaky network filesystem; remount and retry.
  4. Because settingsParseError is set, fix the perms BEFORE making settings changes in-session or they will not persist.

Example fix

# before:
ls -l ~/.config/micro/settings.json   # -rw------- root root
# startup -> Error reading settings.json file: ... permission denied

# after:
sudo chown $USER:$USER ~/.config/micro/settings.json
chmod 644 ~/.config/micro/settings.json
Defensive patterns

Strategy: validation

Validate before calling

func readableSettingsFile(dir string) error {
    p := filepath.Join(dir, "settings.json")
    fi, err := os.Stat(p)
    if err != nil {
        return nil // absent file is fine
    }
    if fi.IsDir() {
        return errors.New("settings.json is a directory")
    }
    f, err := os.Open(p)
    if err != nil {
        return err // permission problem
    }
    f.Close()
    return nil
}

Try / catch

if err := config.ReadSettings(); err != nil {
    if strings.HasPrefix(err.Error(), "Error reading settings.json file:") {
        // I/O failure: fix perms before letting the user edit settings (parse error guard is set)
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: Config dirs previously written by `sudo micro` leaving root-owned files, restore from backup with wrong permissions, or filesystem errors on network mounts.

Related errors


AI-assisted analysis of micro-editor/micro@1c8b82b32e (2026-08-15). Data as JSON: /api/errors/65e426cec0e52555. Report an issue: GitHub.