plandex-ai/plandex · error

error updating settings: %v

Error message

error updating settings: %v

What it means

SyncPlanModelSettings pushes the merged settings back to the server via api.Client.UpdateSettings. If UpdateSettings returns an error, this message is thrown. Note the code wraps `err` (the earlier GetSettings error variable, which is nil at this point) instead of `updateErr`, so the printed message will read 'error updating settings: %!v(<nil>)'-style — the real cause is hidden in updateErr.

Source

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

// 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
}

func SyncDefaultModelSettings() error {
	settings, err := api.Client.GetOrgDefaultSettings()
	if err != nil {
		return fmt.Errorf("error getting settings: %v", err)
	}

	updatedSettings, apiErr := ApplyModelSettings(DefaultModelSettingsPath, settings)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Fix the wrapping bug first: return `fmt.Errorf("error updating settings: %w", updateErr)` so the real API error is visible.
  2. Re-authenticate if the (now-visible) error is 401/403; re-run sync after login.
  3. Re-fetch settings and re-apply if the error indicates a conflict — the server may have newer settings.
  4. Check connectivity and retry; verify CurrentPlanId/CurrentBranch are valid for an update (404).

Example fix

// before (wraps stale/nil err)
if updateErr != nil {
    return fmt.Errorf("error updating settings: %v", err)
}
// after
if updateErr != nil {
    return fmt.Errorf("error updating settings: %w", updateErr)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: confirm the target still exists server-side
settings, err := lib.Client.GetSettings(planID, branch)
if err != nil {
    return fmt.Errorf("cannot update settings for missing plan/branch: %w", err)
}
_ = settings

Type guard

func isConflict(err error) bool { return err != nil && strings.Contains(err.Error(), "409") }

Try / catch

err := lib.SyncPlanModelSettings()
if err != nil && strings.Contains(err.Error(), "error updating settings") {
    // the library wraps the wrong (nil) variable — the real cause is hidden;
    // re-fetch and retry, or upgrade the library for the updateErr wrap fix
    if isConflict(err) { return refetchAndReapply() }
    return retryWithBackoff(3, time.Second, lib.SyncPlanModelSettings)
}

Prevention

When it happens

Trigger: UpdateSettings fails: auth expired (401/403), plan/branch not found (404), request body rejected by validation (400), conflict from concurrent edits (409), network failure or timeout during the write.

Common situations: Another session updated settings concurrently causing a conflict; token expired mid-session after a long-running command; server rejects the custom model pack shape; offline/laptop sleep during sync.

Related errors


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