siyuan-note/siyuan · error
tool handler is not configured
Error message
tool handler is not configured
What it means
The tool being invoked has neither a `ContextHandler` nor a `Handler` function set on its definition, so the dispatch at `server.go:296-301` falls through to the `else` branch. This is an internal registration defect: a tool was registered with `server.AddTool` but its `Tool` struct was not populated with a callable handler.
Source
Thrown at kernel/mcp/server.go:301
if errors.Is(err, model.ErrEncryptedBoxNotUnlocked) {
return toolErrorResult("encrypted notebook is locked, please unlock it first"), nil
}
logging.LogWarnf("mcp: acquire encrypted notebook operations for tool [%s] failed: %v", name, err)
return toolErrorResult(err.Error()), nil
}
}
defer releaseBoxLeases()
var (
result tools.CallToolResult
err error
)
if tool.ContextHandler != nil {
result, err = tool.ContextHandler(ctx, arguments)
} else if tool.Handler != nil {
result, err = tool.Handler(arguments)
} else {
err = fmt.Errorf("tool handler is not configured")
}
if err != nil {
return toolErrorResult(err.Error()), nil
}
if err = validator.ValidateOutputContext(ctx, result); err != nil {
return toolErrorResult(fmt.Sprintf(
"invalid tool output after execution; execution result may have side effects and must not be retried automatically: %v",
err)), nil
}
content := make([]mcpsdk.Content, 0, len(result.Content))
for _, item := range result.Content {
converted, convertErr := convertContentItem(item)
if convertErr != nil {
return toolErrorResult(fmt.Sprintf(
"invalid tool content after execution; execution result may have side effects and must not be retried automatically: %v",
convertErr)), nil
}View on GitHub (pinned to 251596fc0d)
Solutions
- Locate the tool registration in `kernel/mcp/tools/*.go` and confirm the `Handler` (or `ContextHandler`) field is assigned.
- Rebuild/restart the kernel after fixing the registration so the corrected tool table is loaded.
- Add a unit test that asserts every registered tool has at least one handler set.
Example fix
// before
tools.Tool{Name: "foo", InputSchema: sch}
// after
tools.Tool{Name: "foo", InputSchema: sch, Handler: fooHandler} Defensive patterns
Strategy: validation
Validate before calling
// Registry self-check: every registered tool must define a handler.
for _, t := range registeredTools {
if t.Handler == nil && t.ContextHandler == nil {
panic(fmt.Sprintf("tool %q has no handler configured", t.Name))
}
} Prevention
- Assert at registration time that every Tool has Handler or ContextHandler set.
- Add a unit test enumerating the tool registry and checking handler presence.
- Run the test suite after refactoring tool definitions.
When it happens
Trigger: Calling any MCP tool whose `Tool` definition omitted both `Handler` and `ContextHandler`. Always reproducible for that tool name — it is a code/registration bug, not a runtime/transient condition.
Common situations: A tool was added to the registry with only metadata (name, schema) but its handler wiring was forgotten during refactoring. A conditional registration path that skips handler assignment under a feature flag.
Related errors
- full-manual mode requires 'push' or 'pull' subcommand
- tools/list returned an empty response
- tools/list repeated cursor %q
- tools/list exceeded %d pages
- unsupported server type: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/4e7d651d6f1139aa.
Report an issue: GitHub.