{"record":{"id":"2b642bb4de211834","repo":"siyuan-note/siyuan","slug":"tool-execution-was-cancelled-before-it-started","errorCode":null,"errorMessage":"tool execution was cancelled before it started","messagePattern":"tool execution was cancelled before it started","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/agent/tools.go","lineNumber":48,"sourceCode":"\ntype executedToolResult struct {\n\tText             string\n\tModelAttachments []tools.ModelAttachment\n\tIsError          bool\n\tExecutionUnknown bool\n}\n\n// validateToolCallInput 在确认和快照之前校验工具调用，避免无效调用被误判为写操作。\nfunc validateToolCallInput(ctx context.Context, toolName string, args map[string]any) (*tools.Tool, *tools.ToolValidator, error) {\n\tt, validator := tools.LookupToolWithValidator(toolName)\n\tif t == nil {\n\t\treturn nil, nil, fmt.Errorf(\"unknown tool: %s\", toolName)\n\t}\n\tif t.ContextHandler == nil && t.Handler == nil {\n\t\treturn nil, nil, fmt.Errorf(\"tool handler unavailable: %s\", toolName)\n\t}\n\tif ctx.Err() != nil {\n\t\treturn nil, nil, fmt.Errorf(\"tool execution was cancelled before it started\")\n\t}\n\tif err := validator.ValidateInputContext(ctx, args); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"invalid tool arguments: %w\", err)\n\t}\n\treturn t, validator, nil\n}\n\nfunc validateCapabilityCall(ctx context.Context, registration *capabilityRegistration, args map[string]any) error {\n\tif registration == nil {\n\t\treturn fmt.Errorf(\"capability was not exposed in this model round\")\n\t}\n\tif !capabilityStillExecutable(registration, args) {\n\t\treturn fmt.Errorf(\"capability is disabled or no longer available: %s\", registration.ID)\n\t}\n\tif ctx.Err() != nil {\n\t\treturn fmt.Errorf(\"capability execution was cancelled before it started\")\n\t}\n\tif registration.Validator == nil {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/agent/tools.go#L30-L66","documentation":"Before validating arguments, validateToolCallInput checks ctx.Err() and aborts if the context is already cancelled or its deadline has expired. The tool call never starts; the error communicates that cancellation happened upstream so callers do not misattribute the failure to the tool itself.","triggerScenarios":"Executing a tool call with a context that was cancelled (ctx.CancelFunc called) or whose deadline timed out before validateToolCallInput ran — e.g. the HTTP request shut down, the session ended, or a parent deadline expired while the call was queued.","commonSituations":"Client disconnects mid agent run; a model round's overall timeout elapses before the tool dispatch; shutdown path cancels worker contexts while queued tool calls are processed.","solutions":["Check why the context was cancelled: inspect upstream timeout/deadline settings and increase them if the budget is too small.","Skip re-dispatching the tool call after cancellation; treat it as an intentional abort and let the agent round end.","Ensure contexts are only cancelled after in-flight tool calls are drained during shutdown."],"exampleFix":"// before\nresult, err := runAgentRound(ctx) // ctx already cancelled\n// after\nif ctx.Err() != nil {\n    ctx = context.Background() // or create a fresh deadline-scoped ctx before the round\n}\nresult, err := runAgentRound(ctx)","handlingStrategy":"try-catch","validationCode":"if ctx.Err() != nil {\n    return nil, fmt.Errorf(\"cannot dispatch tool: %w\", ctx.Err())\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := validateToolCallInput(ctx, name, args); err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { /* abort round gracefully */ }\n}","preventionTips":["Set realistic per-round deadlines before dispatching tool calls","Drain queued tool calls before cancelling contexts on shutdown","Create a fresh context per model round instead of reusing long-lived ones"],"tags":["context","cancellation","timeout"],"backgroundTag":"request-timeout","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}