plandex-ai/plandex · error

error applying model settings: %v

Error message

error applying model settings: %v

What it means

SyncPlanModelSettings calls ApplyModelSettings on the local plan settings file to merge local model-pack changes into the fetched server settings. If ApplyModelSettings returns an error (file read, validation, copy, or hash-save failure inside it), it is wrapped here. Caution: this line wraps `err` (the GetSettings error variable) instead of `apiErr`, so the message can misreport the underlying cause — a common source of confusing diagnostics.

Source

Thrown at app/cli/lib/model_settings.go:207

	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{
		ModelPackName: updatedSettings.ModelPackName,
		ModelPack:     updatedSettings.ModelPack,
	})

	if updateErr != nil {
		return fmt.Errorf("error updating settings: %v", err)
	}

	if res == nil {
		return nil
	}

	fmt.Println(res.Msg)

	return nil

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the inner error: if it mentions the settings file path, re-create the file (e.g. via checkout) before syncing.
  2. Fix JSON validation errors reported above the error (ValidateModelPackInlineJSON prints details) in the settings file.
  3. Fix the wrapping bug: change `fmt.Errorf("error applying model settings: %v", err)` to wrap `apiErr` so future errors point at the real cause.
  4. Check write permissions on the directory where SaveModelPackRolesHash stores the hash file.

Example fix

// before (bug: wraps wrong variable)
updatedSettings, apiErr := ApplyModelSettings(GetPlanModelSettingsPath(CurrentPlanId), settings)
if apiErr != nil {
    return fmt.Errorf("error applying model settings: %v", err)
}
// after
updatedSettings, apiErr := ApplyModelSettings(GetPlanModelSettingsPath(CurrentPlanId), settings)
if apiErr != nil {
    return fmt.Errorf("error applying model settings: %w", apiErr)
}
Defensive patterns

Strategy: validation

Validate before calling

path := lib.GetPlanModelSettingsPath(planID)
if _, err := os.Stat(path); os.IsNotExist(err) {
    return fmt.Errorf("no local settings at %s; run checkout first before SyncPlanModelSettings", path)
}
data, _ := os.ReadFile(path)
if jerr := json.Unmarshal(data, &json.RawMessage{}); jerr != nil {
    return fmt.Errorf("local settings invalid JSON, ApplyModelSettings will fail: %w", jerr)
}

Type guard

func localSettingsReady(path string) bool {
    data, err := os.ReadFile(path)
    if err != nil { return false }
    var v any
    return json.Unmarshal(data, &v) == nil
}

Try / catch

err := lib.SyncPlanModelSettings()
if err != nil && strings.Contains(err.Error(), "error applying model settings") {
    // NOTE: library wraps the wrong variable here; inspect the inner text,
    // fix the settings file, and retry
    log.Warnf("apply failed: %v", err)
    return regenerateLocalSettingsThenRetry()
}

Prevention

When it happens

Trigger: ApplyModelSettings fails: the settings file is missing or unreadable, ValidateModelPackInlineJSON rejects the JSON (which also os.Exit(1)s), DeepCopy fails, or SaveModelPackRolesHash fails writing the hash file.

Common situations: The plan settings file was deleted before sync; the JSON was hand-edited into an invalid model pack; the hash sidecar file's directory is read-only; running sync before any local settings were ever written.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/d99dfc7a415308b6. Report an issue: GitHub.