plandex-ai/plandex · error

error getting plan config: %v

Error message

error getting plan config: %v

What it means

This error wraps a failure from api.Client.GetPlanConfig(lib.CurrentPlanId) in set_model's parallel fetch. It fires only when lib.CurrentPlanId is non-empty, meaning the plan-specific config lookup failed. The *shared.ApiError Msg is embedded into 'error getting plan config: %s'.

Source

Thrown at app/cli/cmd/set_model.go:187

	}()

	go func() {
		var apiErr *shared.ApiError
		defaultConfig, apiErr = api.Client.GetDefaultPlanConfig()
		if apiErr != nil {
			errCh <- fmt.Errorf("error getting default config: %v", apiErr.Msg)
			return
		}

		errCh <- nil
	}()

	go func() {
		if lib.CurrentPlanId != "" {
			var apiErr *shared.ApiError
			planConfig, apiErr = api.Client.GetPlanConfig(lib.CurrentPlanId)
			if apiErr != nil {
				errCh <- fmt.Errorf("error getting plan config: %v", apiErr.Msg)
				return
			}
		}
		errCh <- nil
	}()

	for i := 0; i < 3; i++ {
		err := <-errCh
		if err != nil {
			term.OutputErrorAndExit(err.Error())
			return nil
		}
	}

	useJsonFile := setModelUseJsonFile || setModelSave

	var nameArg string
	if len(args) > 0 {

View on GitHub (pinned to e2d772072e)

Solutions

  1. Refresh local plan state (re-login or re-select the plan) so CurrentPlanId points to an existing plan
  2. Check err.Msg for 404 — the plan may have been deleted; clear the stale plan ID
  3. Re-authenticate if the error indicates 401/403
  4. Retry on 5xx; verify network connectivity

Example fix

// before
planConfig, apiErr = api.Client.GetPlanConfig(lib.CurrentPlanId)
if apiErr != nil {
	errCh <- fmt.Errorf("error getting plan config: %v", apiErr.Msg)
	return
}
// after
planConfig, apiErr = api.Client.GetPlanConfig(lib.CurrentPlanId)
if apiErr != nil {
	if apiErr.Status == 404 {
		lib.CurrentPlanId = "" // clear stale plan and fall back to default config
	}
	errCh <- fmt.Errorf("error getting plan config: %v", apiErr.Msg)
	return
}
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-flight: verify CurrentPlanId is set and the plan still exists
if lib.CurrentPlanId == "" {
	// proceed with default config instead
}
_, err := api.Client.GetPlanConfig(lib.CurrentPlanId)
if ae, ok := err.(*shared.ApiError); ok && ae.Status == 404 {
	lib.CurrentPlanId = "" // clear stale plan reference
}

Type guard

func planExists(id string) bool {
	_, err := api.Client.GetPlanConfig(id)
	ae, ok := err.(*shared.ApiError)
	return err == nil || (ok && ae.Status != 404)
}

Try / catch

planConfig, apiErr := api.Client.GetPlanConfig(lib.CurrentPlanId)
if apiErr != nil {
	if apiErr.Status == 404 {
		lib.CurrentPlanId = ""
		planConfig, apiErr = api.Client.GetDefaultPlanConfig() // fallback
	}
	if apiErr != nil {
		return fmt.Errorf("error getting plan config: %w", apiErr)
	}
}

Prevention

When it happens

Trigger: CurrentPlanId set (user has an active plan) but GetPlanConfig returns non-nil *shared.ApiError: the plan was deleted or the ID is stale, credentials are invalid/expired, or the server errors on the lookup.

Common situations: Stale plan ID cached after the plan was deleted or access revoked on the server; switching orgs without refreshing local state; token expiry.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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