github/copilot-sdk · error

failed to unmarshal arguments into %T

Error message

failed to unmarshal arguments into %T: %w

What it means

After marshaling, the arguments are unmarshaled into the tool's typed parameter struct T. If the arguments do not match the struct's field types/requirements, json.Unmarshal fails and the error is wrapped with this message including the target type. It means the caller supplied arguments that don't fit the tool's declared parameter schema.

Solutions

  1. Read the wrapped unmarshal error: it names the offending field and expected type
  2. Compare the sent arguments against the tool's input schema and correct types/field names
  3. Ensure required fields are present and JSON types match the Go struct (e.g. no stringified numbers)
  4. If the schema changed, update clients to the new argument shape

Example fix

// before
{"count": "3"}        // string where int expected
// after
{"count": 3}          // correct JSON type for params.Count int
Defensive patterns

Strategy: validation

Validate before calling

// validate arguments against the tool schema before invoking
jsonBytes, _ := json.Marshal(args)
var probe MyToolParams
if err := json.Unmarshal(jsonBytes, &probe); err != nil { /* reject early */ }

Try / catch

// Go
res, err := tool.Invoke(inv)
var typeErr *json.UnmarshalTypeError
if err != nil && errors.As(err, &typeErr) {
	// typeErr.Field names the mismatched argument field
}

Prevention

When it happens

Trigger: Calling a tool with a missing required field, wrong JSON type (string where number expected), or a value failing a custom UnmarshalJSON — anything that makes the round-trip into T fail.

Common situations: LLM or client sending malformed tool arguments; API surface changed (renamed/retyped field) while callers send the old shape; numbers sent as strings; nested objects not matching struct tags.

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 github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/e2a02f005b391d94. Report an issue: GitHub.

Appendix: source

Thrown at go/definetool.go:56

		Parameters:  schema,
		Handler:     createTypedHandler(handler),
	}
}

// createTypedHandler wraps a typed handler function into the standard ToolHandler signature.
func createTypedHandler[T any, U any](handler func(T, ToolInvocation) (U, error)) ToolHandler {
	return func(inv ToolInvocation) (ToolResult, error) {
		var params T

		// Convert arguments to typed struct via JSON round-trip
		// Arguments is already map[string]any from JSON-RPC parsing
		jsonBytes, err := json.Marshal(inv.Arguments)
		if err != nil {
			return ToolResult{}, fmt.Errorf("failed to marshal arguments: %w", err)
		}

		if err := json.Unmarshal(jsonBytes, &params); err != nil {
			return ToolResult{}, fmt.Errorf("failed to unmarshal arguments into %T: %w", params, err)
		}

		result, err := handler(params, inv)
		if err != nil {
			return ToolResult{}, err
		}

		return normalizeResult(result)
	}
}

// normalizeResult converts any value to a ToolResult.
// Strings pass through directly, ToolResult passes through, and other types
// are JSON-serialized.
func normalizeResult(result any) (ToolResult, error) {
	if result == nil {
		return ToolResult{
			TextResultForLLM: "",

View on GitHub (pinned to cd8cf15dc3)