aaif-goose/goose · error

Planner returned no agent-visible text to classify

Error message

Planner returned no agent-visible text to classify

What it means

In plan mode, goose sends the conversation to a planner model and classifies the reply as Plan or ClarifyingQuestions by scanning its agent-visible text (content the model sees, excluding hidden or tool-only payloads). planner_classification_text fails when that text is empty or whitespace-only, so classification cannot proceed.

Source

Thrown at crates/goose-cli/src/session/mod.rs:291

            &model_config,
            "Reply only with the classification label: \"plan\" or \"clarifying questions\"",
            &[message],
            &[],
        ),
    )
    .await?;

    let predicted = result.as_concat_text();
    if predicted.to_lowercase().contains("plan") {
        Ok(PlannerResponseType::Plan)
    } else {
        Ok(PlannerResponseType::ClarifyingQuestions)
    }
}

fn planner_classification_text(response: &Message) -> Result<String> {
    let text = response.agent_visible_content().as_concat_text();
    anyhow::ensure!(
        !text.trim().is_empty(),
        "Planner returned no agent-visible text to classify"
    );
    Ok(text)
}

impl CliSession {
    #[allow(clippy::too_many_arguments)]
    pub async fn new(
        agent: Agent,
        session_id: String,
        debug: bool,
        scheduled_job_id: Option<String>,
        max_turns: Option<u32>,
        edit_mode: Option<EditMode>,
        retry_config: Option<RetryConfig>,
        output_format: String,
        stats: bool,

View on GitHub (pinned to 3810898a74)

Solutions

  1. Retry the plan request — empty completions are usually transient
  2. Validate GOOSE_PLANNER_MODEL and its provider credentials (goose configure)
  3. Switch the planner to a known-good model (or unset the variable to use the default)
  4. Run with --debug to inspect the raw planner response

Example fix

# before
export GOOSE_PLANNER_MODEL=provider/empty-reply-model
# after
unset GOOSE_PLANNER_MODEL   # fall back to the configured default model
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..3 {
    match planner_classification_text(&response).await {
        Ok(text) => break text,
        Err(e) if attempt < 2 && e.to_string().contains("no agent-visible text") => {
            response = ask_planner(&messages).await?;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Invoking the plan flow (/plan or the planner path in session/mod.rs) when the planner model returns an empty completion, filtered content, or a response containing only non-agent-visible content.

Common situations: GOOSE_PLANNER_MODEL pointing at a model that returns empty bodies; provider outages returning empty content; reasoning-only responses with no text part.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/5f46535155f6407a. Report an issue: GitHub.