plandex-ai/plandex · error
error writing model settings file: %v
Error message
error writing model settings file: %v
What it means
When the local hash differs from the server hash, WriteModelSettingsFile(path, settings) overwrites the local file with the server settings. If that write fails (permission, serialization, or rename failure inside the helper), the error is wrapped as this message. The function then aborts with the local file left stale.
Source
Thrown at app/cli/lib/model_settings.go:192
}
settings, apiErr := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
if apiErr != nil {
return false, fmt.Errorf("error getting settings: %v", apiErr)
}
serverHash, err := settings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles.Hash()
if err != nil {
return false, fmt.Errorf("error hashing model pack: %v", err)
}
if localHash == serverHash {
return false, nil
}
err = WriteModelSettingsFile(path, settings)
if err != nil {
return false, fmt.Errorf("error writing model settings file: %v", err)
}
return true, nil
}
// save settings in file to server
func SyncPlanModelSettings() error {
settings, err := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
if err != nil {
return fmt.Errorf("error getting settings: %v", err)
}
updatedSettings, apiErr := ApplyModelSettings(GetPlanModelSettingsPath(CurrentPlanId), settings)
if apiErr != nil {
return fmt.Errorf("error applying model settings: %v", err)
}
res, updateErr := api.Client.UpdateSettings(CurrentPlanId, CurrentBranch, shared.UpdateSettingsRequest{View on GitHub (pinned to e2d772072e)
Solutions
- Fix permissions on the settings file and its directory: chown to the current user and ensure write access (chmod u+w).
- Check disk space (df -h) and free space if the filesystem is full.
- Ensure the parent directory returned by GetPlanModelSettingsPath exists (mkdir -p).
- If marshaling fails (inner error mentions json), update the CLI so WriteModelSettingsFile supports the server settings schema.
Example fix
// before
err = WriteModelSettingsFile(path, settings)
if err != nil {
return false, fmt.Errorf("error writing model settings file: %v", err)
}
// after: ensure the directory exists before writing
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return false, fmt.Errorf("error creating settings dir: %w", err)
}
if err := WriteModelSettingsFile(path, settings); err != nil {
return false, fmt.Errorf("error writing model settings file: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
path := lib.GetPlanModelSettingsPath(planID)
dir := filepath.Dir(path)
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
os.MkdirAll(dir, 0o755)
}
if err := unix.Access(path, unix.W_OK); err != nil && os.Getenv("SKIP_CHECK") == "" {
return fmt.Errorf("settings file not writable: %w", err)
} Type guard
func writable(path string) bool {
f, err := os.OpenFile(path, os.O_WRONLY, 0)
if err == nil { f.Close(); return true }
return false
} Try / catch
updated, err := lib.SaveLatestPlanModelSettingsIfNeeded()
if err != nil && strings.Contains(err.Error(), "error writing model settings file") {
log.Warnf("could not persist server settings locally (permissions/disk?): %v", err)
// proceed; local file stays stale and will retry next run
return nil
} Prevention
- Keep one owning user for the settings directory; avoid sudo-created files.
- Monitor disk space on the volume holding the settings dir.
- Ensure the settings directory exists before running sync commands.
- Treat this as non-fatal when possible — the next sync will retry the write.
When it happens
Trigger: WriteModelSettingsFile fails: the settings file or its directory is read-only or owned by another user, the disk is full, settings cannot be marshaled to JSON, or the parent directory does not exist.
Common situations: Running the CLI as a different user than the one who owns the settings file (root vs user); read-only home mount in a container; full disk; settings directory deleted while the CLI was running.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- error walking directory: %s
- failed to check if %s exists: %s
- failed to read %s: %s
- failed to write %s: %s
- failed to remove %s: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a819e3b1bc323c93.
Report an issue: GitHub.