{"record":{"id":"75da117ea627de4f","repo":"siyuan-note/siyuan","slug":"capability-execution-was-cancelled-before-it-start","errorCode":null,"errorMessage":"capability execution was cancelled before it started","messagePattern":"capability execution was cancelled before it started","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/agent/tools.go","lineNumber":64,"sourceCode":"\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 {\n\t\treturn fmt.Errorf(\"capability validator unavailable: %s\", registration.ID)\n\t}\n\tif err := registration.Validator.ValidateInputContext(ctx, args); err != nil {\n\t\treturn fmt.Errorf(\"invalid capability arguments: %w\", err)\n\t}\n\tif !registration.isBrowser() &&\n\t\t(registration.Tool == nil || registration.Tool.ContextHandler == nil && registration.Tool.Handler == nil) {\n\t\treturn fmt.Errorf(\"capability handler unavailable: %s\", registration.ID)\n\t}\n\treturn nil\n}\n\n// executeTool 执行单次工具调用。\nfunc executeTool(ctx context.Context, tc openai.ToolCall, sessionID string) executedToolResult {\n\ttool, validator := tools.LookupToolWithValidator(tc.Function.Name)\n\tif tool == nil {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/tools.go#L46-L82","documentation":"validateCapabilityCall checks ctx.Err() before executing and rejects the call when the context is already cancelled or its deadline exceeded. This prevents starting capability work (LLM tool execution, possibly writes) after the request was aborted or timed out.","triggerScenarios":"The HTTP request driving the agent round was cancelled by the client, the per-round context deadline expired before the tool call was validated, or the user hit stop/cancel in the UI while the model was streaming a tool call.","commonSituations":"User cancels a long AI chat, browser tab closes mid-request, gateway/proxy timeout kills the request, or deadline set too aggressively for slow tool calls.","solutions":["Check upstream context creation; raise deadlines if tool calls legitimately need longer","Ignore/log this result when the caller itself initiated cancellation (it is expected, not a bug)","In the agent loop, stop scheduling further rounds once ctx.Err() != nil","Verify the client (UI or HTTP caller) is not aborting requests prematurely"],"exampleFix":"// before: one global short deadline for the whole agent run\nctx, cancel := context.WithTimeout(ctx, 5*time.Second)\n// after: budget enough time for tool execution\nctx, cancel := context.WithTimeout(ctx, 2*time.Minute)","handlingStrategy":"validation","validationCode":"if ctx.Err() != nil {\n    return executedToolResult{Text: \"cancelled\", IsError: true}\n}","typeGuard":null,"tryCatchPattern":"select {\ncase <-ctx.Done():\n    return executedToolResult{Text: \"capability execution was cancelled before it started\", IsError: true}\ndefault:\n    // proceed\n}","preventionTips":["Set generous deadlines covering tool execution time","Check ctx.Err() before scheduling each agent round","Distinguish caller-initiated cancellation from unexpected timeouts in logging"],"tags":["ai","context","cancellation","timeout"],"backgroundTag":"request-timeout","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}