{"record":{"id":"15cd185ead31d31b","repo":"vxcontrol/pentagi","slug":"no-subtasks-generated-for-task-d","errorCode":null,"errorMessage":"no subtasks generated for task %d","messagePattern":"no subtasks generated for task (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/subtasks.go","lineNumber":78,"sourceCode":"\t\t\t}\n\n\t\t\treturn fmt.Errorf(\"failed to create subtask worker: %w\", err)\n\t\t}\n\n\t\tstc.subtasks[subtask.ID] = st\n\t}\n\n\treturn nil\n}\n\nfunc (stc *subtaskController) GenerateSubtasks(ctx context.Context) error {\n\tplan, err := stc.taskCtx.Provider.GenerateSubtasks(ctx, stc.taskCtx.TaskID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to generate subtasks for task %d: %w\", stc.taskCtx.TaskID, err)\n\t}\n\n\tif len(plan) == 0 {\n\t\treturn fmt.Errorf(\"no subtasks generated for task %d\", stc.taskCtx.TaskID)\n\t}\n\n\t// TODO: change it to insert subtasks in transaction\n\tfor _, info := range plan {\n\t\t_, err := stc.taskCtx.DB.CreateSubtask(ctx, database.CreateSubtaskParams{\n\t\t\tStatus:      database.SubtaskStatusCreated,\n\t\t\tTaskID:      stc.taskCtx.TaskID,\n\t\t\tTitle:       info.Title,\n\t\t\tDescription: info.Description,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create subtask for task %d: %w\", stc.taskCtx.TaskID, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/subtasks.go#L60-L96","documentation":"Returned when Provider.GenerateSubtasks succeeds but returns an empty plan — the LLM produced no usable subtasks. The controller refuses to continue with zero subtasks since the task would have nothing to execute. Note the error carries no wrapped cause; it is a semantic validation of the provider output.","triggerScenarios":"GenerateSubtasks receives len(plan) == 0 after a successful provider call — the model returned an empty list, or the provider's parsing produced no entries from the response.","commonSituations":"Model too weak/small to follow the plan-generation prompt; temperature/prompt configuration producing empty structured output; custom provider returning an empty array on parse quirks; task description too vague for the model to decompose.","solutions":["Retry generation — LLMs can return empty output nondeterministically; a re-run often yields a valid plan.","Improve the task title/description to be more specific so the model can decompose it.","Switch to a stronger model/provider for plan generation in Settings.","Review the provider's GenerateSubtasks parsing logic — a response-format mismatch may silently drop all entries.","Adjust the plan-generation prompt template in the prompt settings."],"exampleFix":"// before: single-shot generation\nif err := stc.GenerateSubtasks(ctx); err != nil { return err }\n// after: validate inputs and retry once on empty plan\nif task.Description == \"\" { return fmt.Errorf(\"task %d has no description\", taskID) }\nif err := stc.GenerateSubtasks(ctx); err != nil {\n    if strings.Contains(err.Error(), \"no subtasks generated\") {\n        return stc.GenerateSubtasks(ctx)\n    }\n    return err\n}","handlingStrategy":"validation","validationCode":"// ensure the task has enough context for the model to decompose\nif len(strings.TrimSpace(task.Description)) < 20 {\n    return fmt.Errorf(\"task description too short for subtask generation\")\n}","typeGuard":"func hasUsablePlan(plan []providers.SubtaskInfo) bool {\n    return len(plan) > 0\n}","tryCatchPattern":"err := stc.GenerateSubtasks(ctx)\nif err != nil && strings.Contains(err.Error(), \"no subtasks generated\") {\n    // empty LLM output: retry once, then surface to the user\n    if retryErr := stc.GenerateSubtasks(ctx); retryErr != nil {\n        return retryErr\n    }\n}","preventionTips":["Require a meaningful task title/description before allowing plan generation.","Use a strong model for plan generation; small models often return empty plans.","Retry empty plans automatically once — LLM output is nondeterministic.","Check the provider's structured-output parsing to ensure entries aren't silently dropped."],"tags":["llm","empty-response","subtask-generation","validation"],"backgroundTag":"llm-empty-response","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}