siyuan-note/siyuan · error
tool is nil
Error message
tool is nil
What it means
CompileToolValidator refuses to build a validator when the *Tool pointer is nil. This library compiles JSON-Schema validators for MCP tools, and validating a nil tool has no meaningful schema, so it fails fast with a clear error instead of panicking later on a nil dereference. It is a defensive guard at the entry of validator compilation.
Source
Thrown at kernel/mcp/tools/validation.go:48
maxToolSchemaBytes = 1 << 20
maxToolSchemaDepth = 64
maxToolSchemaNodes = 16 << 10
maxToolValueBytes = 8 << 20
maxToolValueDepth = 128
maxToolValueNodes = 256 << 10
toolValidationTime = 2 * time.Second
toolValidationConcurrency = 4
)
type ToolValidator struct {
input *jsonschema.Resolved
output *jsonschema.Resolved
validationSlots chan struct{}
}
func CompileToolValidator(tool *Tool) (*ToolValidator, error) {
if tool == nil {
return nil, fmt.Errorf("tool is nil")
}
input, err := resolveToolSchema(tool.InputSchema, true)
if err != nil {
return nil, fmt.Errorf("invalid input schema: %w", err)
}
var output *jsonschema.Resolved
if tool.OutputSchema != nil {
if output, err = resolveToolSchema(*tool.OutputSchema, false); err != nil {
return nil, fmt.Errorf("invalid output schema: %w", err)
}
}
return &ToolValidator{
input: input,
output: output,
validationSlots: make(chan struct{}, toolValidationConcurrency),
}, nilView on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the *Tool passed to CompileToolValidator is non-nil; check the return value of whatever constructs the tool.
- In SetTool/buildCapabilitySet, skip or log registry entries with nil Tool instead of compiling them.
- Fix the upstream constructor so it returns an error rather than a nil tool.
Example fix
// before
v, err := CompileToolValidator(tool)
// after
if tool == nil {
return fmt.Errorf("tool %q is not defined", name)
}
v, err := CompileToolValidator(tool) Defensive patterns
Strategy: type-guard
Validate before calling
if tool == nil {
return errors.New("cannot compile validator: tool is nil")
} Type guard
func toolDefined(t *tools.Tool) bool { return t != nil } Try / catch
v, err := tools.CompileToolValidator(tool)
if err != nil {
if strings.Contains(err.Error(), "tool is nil") {
return fmt.Errorf("tool %q missing definition", name)
}
return err
} Prevention
- Never allow tool factories to return nil without an error
- Check for nil immediately after decoding/deserializing tool definitions
- Add a nil check in registration wrappers before calling CompileToolValidator
When it happens
Trigger: Calling CompileToolValidator(nil), or calling SetTool / buildCapabilitySet with a registry entry whose Tool field is nil (e.g. a registered tool factory returned nil).
Common situations: Constructing tool sets dynamically where a builder function returns nil on some branch; refactoring that removed a tool but left its registration slot; deserializing tool definitions where a missing entry decodes to nil.
Related errors
- invalid input schema: %w
- root type must be "object"
- structured content is required when an output schema is defi
- view not found
- key not found
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/1715c279caa870d8.
Report an issue: GitHub.