siyuan-note/siyuan · error

invalid tool arguments

Error message

invalid tool arguments: %w

What it means

After the tool is found and the context is live, validateToolCallInput runs validator.ValidateInputContext(ctx, args) against the tool's input schema. Any schema validation failure (missing required fields, wrong types, invalid enum values in args) is wrapped as 'invalid tool arguments' with the underlying cause preserved via %w.

Solutions

  1. Read the wrapped cause for the exact field/path that failed and fix the args accordingly
  2. Ensure all required fields per the tool schema (e.g. 'action') are present before calling
  3. Regenerate or update callers after tool schema changes so argument shapes stay in sync
  4. Validate the args map client-side against the same schema before dispatching

Example fix

// before: missing required 'action' argument
args := map[string]any{"path": "/tmp/a.txt"}
validateToolCallInput(ctx, "write_file", args)
// after
args := map[string]any{"path": "/tmp/a.txt", "action": "write"}
validateToolCallInput(ctx, "write_file", args)
Defensive patterns

Strategy: validation

Validate before calling

if _, ok := args["action"]; !ok {
    return errors.New("missing required tool argument: action")
}

Try / catch

if err != nil && strings.HasPrefix(err.Error(), "invalid tool arguments:") {
    var verr error
    errors.As(err, &verr) // unwrap for the exact schema path/field
    return fmt.Errorf("fix arguments before retrying: %w", verr)
}

Prevention

When it happens

Trigger: Calling a tool with args that violate its declared schema: missing a required 'action' field, wrong value types (string vs number), unknown enum values, or extra fields when strict validation applies.

Common situations: LLM produces incomplete or mistyped tool arguments; caller builds args map manually and forgets a required key (e.g. the missing 'action' covered by the related test); schema evolved and older callers still send the previous shape.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/e1a959d015516467. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/tools.go:51

	ModelAttachments []tools.ModelAttachment
	IsError          bool
	ExecutionUnknown bool
}

// validateToolCallInput 在确认和快照之前校验工具调用,避免无效调用被误判为写操作。
func validateToolCallInput(ctx context.Context, toolName string, args map[string]any) (*tools.Tool, *tools.ToolValidator, error) {
	t, validator := tools.LookupToolWithValidator(toolName)
	if t == nil {
		return nil, nil, fmt.Errorf("unknown tool: %s", toolName)
	}
	if t.ContextHandler == nil && t.Handler == nil {
		return nil, nil, fmt.Errorf("tool handler unavailable: %s", toolName)
	}
	if ctx.Err() != nil {
		return nil, nil, fmt.Errorf("tool execution was cancelled before it started")
	}
	if err := validator.ValidateInputContext(ctx, args); err != nil {
		return nil, nil, fmt.Errorf("invalid tool arguments: %w", err)
	}
	return t, validator, nil
}

func validateCapabilityCall(ctx context.Context, registration *capabilityRegistration, args map[string]any) error {
	if registration == nil {
		return fmt.Errorf("capability was not exposed in this model round")
	}
	if !capabilityStillExecutable(registration, args) {
		return fmt.Errorf("capability is disabled or no longer available: %s", registration.ID)
	}
	if ctx.Err() != nil {
		return fmt.Errorf("capability execution was cancelled before it started")
	}
	if registration.Validator == nil {
		return fmt.Errorf("capability validator unavailable: %s", registration.ID)
	}
	if err := registration.Validator.ValidateInputContext(ctx, args); err != nil {

View on GitHub (pinned to 9f775e8a12)