{"record":{"id":"b3a5b0844d9357a4","repo":"vxcontrol/pentagi","slug":"failed-to-perform-agent-chain-for-subtask-d-w","errorCode":null,"errorMessage":"failed to perform agent chain for subtask %d: %w","messagePattern":"failed to perform agent chain for subtask (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/subtask.go","lineNumber":329,"sourceCode":"\t\tmsgChainID = stw.subtaskCtx.MsgChainID\n\t)\n\n\tif err := stw.subtaskCtx.Provider.EnsureChainConsistency(ctx, msgChainID); err != nil {\n\t\tstw.handleInterrupting(err)\n\t\treturn fmt.Errorf(\"failed to ensure chain consistency for subtask %d: %w\", subtaskID, err)\n\t}\n\n\tperformResult, err := stw.subtaskCtx.Provider.PerformAgentChain(ctx, taskID, subtaskID, msgChainID)\n\tif err != nil {\n\t\tif errors.Is(err, context.Canceled) {\n\t\t\tctx = context.Background()\n\t\t}\n\t\terrChainConsistency := stw.subtaskCtx.Provider.EnsureChainConsistency(ctx, msgChainID)\n\t\tif errChainConsistency != nil {\n\t\t\terr = errors.Join(err, errChainConsistency)\n\t\t}\n\t\t_ = stw.SetStatus(ctx, database.SubtaskStatusWaiting)\n\t\treturn fmt.Errorf(\"failed to perform agent chain for subtask %d: %w\", subtaskID, err)\n\t}\n\n\tswitch performResult {\n\tcase providers.PerformResultWaiting:\n\t\tif err := stw.SetStatus(ctx, database.SubtaskStatusWaiting); err != nil {\n\t\t\tstw.handleInterrupting(err)\n\t\t\treturn err\n\t\t}\n\tcase providers.PerformResultDone:\n\t\tif err := stw.SetStatus(ctx, database.SubtaskStatusFinished); err != nil {\n\t\t\tstw.handleInterrupting(err)\n\t\t\treturn fmt.Errorf(\"failed to set subtask %d status to finished: %w\", subtaskID, err)\n\t\t}\n\tcase providers.PerformResultError:\n\t\tif err := stw.SetStatus(ctx, database.SubtaskStatusFailed); err != nil {\n\t\t\tstw.handleInterrupting(err)\n\t\t\treturn fmt.Errorf(\"failed to set subtask %d status to failed: %w\", subtaskID, err)\n\t\t}","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/subtask.go#L311-L347","documentation":"Run executes the LLM agent chain via Provider.PerformAgentChain. On any error from that call, the subtask is reset to Waiting, chain consistency is re-attempted (joined via errors.Join on failure), and the combined error is wrapped as 'failed to perform agent chain for subtask %d'. This is the top-level wrapper for all LLM/tool failures during subtask execution.","triggerScenarios":"PerformAgentChain fails due to: LLM provider API error (invalid key, rate limit, timeout, context cancelled by flow interrupt), tool execution failure inside the Docker sandbox, DB failure while persisting chain messages, or EnsureChainConsistency failing during the post-error cleanup.","commonSituations":"Expired or quota-exhausted LLM API key; network egress blocked from the backend container to the LLM provider; user interrupted the flow cancelling ctx; tool container crashed mid-execution leaving the provider unable to complete the chain.","solutions":["Unwrap with errors.Is/errors.As: context.Canceled means the user/flow interrupted — no fix needed, subtask is already Waiting for resume; retry Run/PutInput later.","For provider auth/quota errors, fix the API key or quota in Settings/env, then re-run the subtask (it stays Waiting).","For network errors, verify egress connectivity/proxy settings to the LLM endpoint and retry.","If errChainConsistency is joined in, reset the subtask's msgchain rows or recreate the subtask — the chain is too corrupted to resume.","Check the specific LLM provider logs and tool container logs for the root cause before retrying."],"exampleFix":"// before\nif err := worker.Run(ctx); err != nil {\n\treturn err\n}\n// after\nif err := worker.Run(ctx); err != nil {\n\tswitch {\n\tcase errors.Is(err, context.Canceled):\n\t\treturn nil // interrupted; subtask already reset to Waiting\n\tcase errors.Is(err, context.DeadlineExceeded):\n\t\treturn fmt.Errorf(\"chain timed out; retry with larger budget: %w\", err)\n\tdefault:\n\t\treturn err\n\t}\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: live context and configured provider before running\nif err := ctx.Err(); err != nil {\n\treturn err\n}\nif apiKey == \"\" {\n\treturn fmt.Errorf(\"LLM provider API key not configured\")\n}","typeGuard":"func classifyChainErr(err error) string {\n\tswitch {\n\tcase errors.Is(err, context.Canceled):\n\t\treturn \"interrupted\"\n\tcase errors.Is(err, context.DeadlineExceeded):\n\t\treturn \"timeout\"\n\tcase strings.Contains(err.Error(), \"401\"), strings.Contains(err.Error(), \"quota\"):\n\t\treturn \"provider-auth\"\n\tdefault:\n\t\treturn \"transient\"\n\t}\n}","tryCatchPattern":"if err := worker.Run(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"failed to perform agent chain\") {\n\t\tswitch classifyChainErr(err) {\n\t\tcase \"interrupted\":\n\t\t\treturn nil // subtask reset to Waiting; resume later\n\t\tcase \"provider-auth\":\n\t\t\treturn fmt.Errorf(\"fix provider key/quota then re-run: %w\", err)\n\t\tcase \"transient\":\n\t\t\t// subtask is Waiting again; retry Run after backoff\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Validate provider API keys/quotas before starting a flow.","Set realistic LLM timeouts and keep contexts alive for long chains.","Monitor egress/proxy connectivity to the LLM endpoint from the backend container.","Inspect joined errors (errors.Join) — a chain-consistency failure may be bundled and need chain reset.","On repeated failures, recreate the subtask instead of infinite retry."],"tags":["go","llm","provider","agent-chain","retryable"],"backgroundTag":"agent-chain-execution-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}