plandex-ai/plandex · error

Error telling plan:

Error message

Error telling plan: 

What it means

This wraps any error returned by modelPlan.Tell when executing the plan's tell operation (starting the LLM-driven plan iteration). The handler responds 500 'Error telling plan: <detail>' with the underlying error text appended, and reports it asynchronously. The appended detail is the key to diagnosing the real cause (model client init, stream start, or plan state).

Source

Thrown at app/server/handlers/plans_exec.go:110

			authVars:      requestBody.AuthVars,
			plan:          plan,
			settings:      settings,
			orgUserConfig: orgUserConfig,
		},
	)
	err = modelPlan.Tell(modelPlan.TellParams{
		Clients:  res.clients,
		Plan:     plan,
		Branch:   branch,
		Auth:     auth,
		Req:      &requestBody,
		AuthVars: res.authVars,
	})

	if err != nil {
		log.Printf("Error telling plan: %v\n", err)
		go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error telling plan: %v", err))
		http.Error(w, "Error telling plan: "+err.Error(), http.StatusInternalServerError)
		return
	}

	if requestBody.ConnectStream {
		startResponseStream(r.Context(), w, auth, planId, branch, false)
	}

	log.Println("Successfully processed request for TellPlanHandler")
}

func BuildPlanHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for BuildPlanHandler", "ip:", host.Ip)
	auth := Authenticate(w, r, true)
	if auth == nil {
		return
	}

	vars := mux.Vars(r)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the appended detail after 'Error telling plan: ' in the response/log — it contains the root cause.
  2. Verify the API keys (request ApiKeys or server env) are valid and have quota for the configured model provider.
  3. Ensure no other tell/build is already active on that plan+branch (connect/stop or wait for the current run to finish).
  4. Check org user config model settings; reset to defaults if a custom model name/provider is misconfigured.
  5. Retry after a provider outage; if persistent, upgrade server and CLI to matching versions.

Example fix

// before: per-request key that may be stale
curl -X POST .../tell -d '{"apiKeys":{"OPENAI_API_KEY":"sk-expired"}}'
// after: rely on validated server-side key or refresh first
export OPENAI_API_KEY=sk-valid
curl -X POST .../tell -d '{}'
Defensive patterns

Strategy: try-catch

Validate before calling

// verify provider credentials before calling tell
if os.Getenv("OPENAI_API_KEY") == "" && len(req.ApiKeys) == 0 {
    return errors.New("no model API key available")
}

Try / catch

if err := modelPlan.Tell(params); err != nil {
    if strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "invalid api key") {
        return fmt.Errorf("refresh credentials: %w", err)
    }
    if isActivePlanErr(err) { return stopAndWaitThenRetry() }
    return err
}

Prevention

When it happens

Trigger: POST to the tell-plan endpoint where modelPlan.Tell fails: invalid/missing API keys passed in requestBody.ApiKeys, unresolvable model provider config from orgUserConfig, an active plan already running on the branch, or internal errors while launching the plan loop.

Common situations: Expired or wrong OpenAI/Anthropic API key supplied per-request; org-level model config pointing at a disabled model; attempting to tell a plan that is already active on the same branch; provider outage surfacing through the model client.

Related errors


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