plandex-ai/plandex · error
No planName tag found in XML response
Error message
No planName tag found in XML response
What it means
GenPlanName requested XML output (PreferredOutputFormat == xml) but the model's returned content did not contain a parseable <planName> element, so utils.GetXMLContent returned an empty string. The library fails fast rather than returning an empty plan name. The model responded, but not in the expected structured shape.
Source
Thrown at app/server/model/name.go:95
Messages: messages,
Tools: tools,
ToolChoice: toolChoice,
SessionId: sessionId,
Settings: settings,
})
if err != nil {
fmt.Printf("Error during plan name model call: %v\n", err)
return "", err
}
var planName string
content := modelRes.Content
if baseModelConfig.PreferredOutputFormat == shared.ModelOutputFormatXml {
planName = utils.GetXMLContent(content, "planName")
if planName == "" {
return "", fmt.Errorf("No planName tag found in XML response")
}
} else {
if content == "" {
fmt.Println("no namePlan function call found in response")
return "", fmt.Errorf("No namePlan function call found in response. The model failed to generate a valid response.")
}
var nameRes prompts.PlanNameRes
err = json.Unmarshal([]byte(content), &nameRes)
if err != nil {
fmt.Printf("Error unmarshalling plan description response: %v\n", err)
return "", err
}
planName = nameRes.PlanName
}
return planName, nil
}View on GitHub (pinned to e2d772072e)
Solutions
- Retry the request; nondeterministic models often emit valid XML on retry
- Strengthen the prompt with an explicit XML schema example for planName
- Use a model known to follow structured output / the provider's native JSON mode
- Preprocess content to strip markdown fences before GetXMLContent
- Fall back to the non-XML branch (function-call content) or a default name if parsing fails
Example fix
// before
planName := utils.GetXMLContent(content, "planName")
if planName == "" { return "", fmt.Errorf("No planName tag found in XML response") }
// after: strip fences then retry once
cleaned := strings.TrimSpace(strings.Trim(content, "` \n"))
planName := utils.GetXMLContent(cleaned, "planName")
if planName == "" { planName = fallbackPlanName() } Defensive patterns
Strategy: fallback
Validate before calling
// request structured output explicitly and verify shape before parsing
if baseModelConfig.PreferredOutputFormat == shared.ModelOutputFormatXml &&
!strings.Contains(modelRes.Content, "<planName>") {
// retry or switch to non-XML extraction path before failing
} Type guard
func hasPlanNameTag(content string) bool {
return strings.Contains(content, "<planName>") && strings.Contains(content, "</planName>")
} Try / catch
name, err := GenPlanName(ctx, ...)
if err != nil && strings.Contains(err.Error(), "No planName tag found") {
name = retryOrExtractFallback(modelRes.Content) // e.g. regex or default name
} Prevention
- Include a concrete XML schema example in the prompt
- Prefer providers' native structured/JSON output modes for weak models
- Strip markdown code fences before XML parsing
- Retry once on parse failure; LLM structured output is nondeterministic
When it happens
Trigger: Model output format is XML and GetXMLContent(content, "planName") yields "": model omitted the tag, used different tag casing/nesting, wrapped XML in markdown fences, or produced prose instead of XML.
Common situations: Weak models ignoring the XML schema instruction; prompt changes dropping the schema example; providers adding code fences around XML; truncation cutting off the closing tag; switching to a model that follows structured output poorly.
Related errors
- no whole file found in response
- old content does not have a line number prefix for first lin
- error extracting line number from first line: %v
- error extracting line number from last line: %v
- error unmarshalling JSON file: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/6b813b3d6f733379.
Report an issue: GitHub.