github/copilot-sdk · error

decode elicitation schema property

Error message

decode elicitation schema property %q: %w

What it means

Once the wrapper schema is marshaled, it is unmarshaled into rpc.UIElicitationSchema to normalize the property. If that decode fails, or the property is missing afterwards (the follow-up 'property missing after conversion' variant), the library returns this error naming the property. It means the property definition could not be re-validated as a proper schema property object.

Solutions

  1. Check the wrapped json.Unmarshal error for the exact decode mismatch
  2. Ensure the property definition marshals to a JSON object with a valid schema 'type'
  3. Pass rpc.UIElicitationSchemaProperty directly to skip the marshal/decode round-trip
  4. Validate the property against the rpc.UIElicitationSchemaProperty struct fields before calling

Example fix

// before
props := map[string]any{"x": []string{"a"}} // array, not schema object
// after
props := map[string]any{"x": map[string]any{"type": "string", "enum": []string{"a"}}}
Defensive patterns

Strategy: validation

Validate before calling

data, err := json.Marshal(property)
if err != nil { return err }
var probe map[string]any
if err := json.Unmarshal(data, &probe); err != nil {
    return fmt.Errorf("property must decode to a schema object: %w", err)
}
if _, ok := probe["type"]; !ok {
    return fmt.Errorf("property missing 'type'")
}

Try / catch

res, err := ui.Elicitation(ctx, msg, schema)
if err != nil && strings.Contains(err.Error(), "decode elicitation schema property") {
    return fmt.Errorf("property is not a valid schema object: %w", err)
}

Prevention

When it happens

Trigger: A marshaled property definition decodes into something the rpc.UIElicitationSchema expects differently (e.g. wrong 'type' value, properties conflicting with the wrapper), causing json.Unmarshal of wrapperData to fail.

Common situations: Property definitions whose 'type' field collides with the wrapper's object type; values marshaling to non-object JSON (strings, arrays) that the rpc schema rejects; version mismatch between the local struct tags and rpc types.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/eace03871c7b0da1. Report an issue: GitHub.

Appendix: source

Thrown at go/session.go:1234

	data, err := json.Marshal(property)
	if err != nil {
		return nil, fmt.Errorf("marshal elicitation schema property %q: %w", name, err)
	}
	wrapperData, err := json.Marshal(struct {
		Properties map[string]json.RawMessage  `json:"properties"`
		Type       rpc.UIElicitationSchemaType `json:"type"`
	}{
		Properties: map[string]json.RawMessage{name: data},
		Type:       rpc.UIElicitationSchemaTypeObject,
	})
	if err != nil {
		return nil, fmt.Errorf("marshal elicitation schema wrapper for property %q: %w", name, err)
	}

	var rpcSchema rpc.UIElicitationSchema
	if err := json.Unmarshal(wrapperData, &rpcSchema); err != nil {
		return nil, fmt.Errorf("decode elicitation schema property %q: %w", name, err)
	}
	rpcProperty, ok := rpcSchema.Properties[name]
	if !ok {
		return nil, fmt.Errorf("decode elicitation schema property %q: property missing after conversion", name)
	}
	return rpcProperty, nil
}

// Confirm shows a confirmation dialog and returns the user's boolean answer.
// Returns false if the user declines or cancels.
func (ui *SessionUI) Confirm(ctx context.Context, message string) (bool, error) {
	if err := ui.session.assertElicitation(); err != nil {
		return false, err
	}
	rpcResult, err := ui.session.RPC.UI.Elicitation(ctx, &rpc.UIElicitationRequest{
		Message: message,
		RequestedSchema: rpc.UIElicitationSchema{
			Type: rpc.UIElicitationSchemaTypeObject,

View on GitHub (pinned to cd8cf15dc3)