dagger/dagger · error

array element must be string, got %T

Error message

array element must be string, got %T

What it means

toStringSlice converts a schema value expected to be a list of strings (e.g. 'required' or 'enum') into []string. When the value is []any, every element must be a string. This error is thrown when one element is a different JSON type (number, bool, object, null), since Google's genai schema requires string-only lists for these fields.

Source

Thrown at core/llm_google.go:682

		}
		return res, nil
	case []map[string]any:
		return x, nil
	default:
		return nil, fmt.Errorf("value must be []map[string]any or []any, got %T", x)
	}
}

func toStringSlice(val any) ([]string, error) {
	var res []string
	switch x := val.(type) {
	case []any:
		for _, v := range x {
			switch y := v.(type) {
			case string:
				res = append(res, y)
			default:
				return nil, fmt.Errorf("array element must be string, got %T", y)
			}
		}
	case []string:
		res = x
	default:
		return nil, fmt.Errorf("value must be []string or []any, got %T", x)
	}
	return res, nil
}

func bbiTypeToGenaiType(bbi string) genai.Type {
	switch bbi {
	case "integer":
		return genai.TypeInteger
	case "number":
		return genai.TypeNumber
	case "string":
		return genai.TypeString

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Make every element of the array a string; for numeric enums, express values as strings or restructure the schema.
  2. For numeric enums, note genai only supports string Enum; convert values with fmt.Sprintf or use description text instead.
  3. Validate enum/required arrays are all-strings before registering the tool.

Example fix

// before
"enum": [1, 2, 3]
// after
"enum": ["1", "2", "3"]
Defensive patterns

Strategy: type-guard

Validate before calling

func validateStringSlice(v any) error {
    arr, ok := v.([]any)
    if !ok { return nil }
    for i, el := range arr {
        if _, ok := el.(string); !ok {
            return fmt.Errorf("element %d is not a string", i)
        }
    }
    return nil
}

Type guard

func allStrings(v any) bool {
    switch x := v.(type) {
    case []string:
        return true
    case []any:
        for _, e := range x {
            if _, ok := e.(string); !ok { return false }
        }
        return true
    }
    return false
}

Try / catch

if err := registerTool(schema); err != nil {
    if strings.Contains(err.Error(), "array element must be string") {
        // coerce or report enum/required elements
    }
}

Prevention

When it happens

Trigger: 'enum' containing non-string values (e.g. enum: [1,2,3] or ["a", null]) or 'required' containing non-string entries (e.g. required: [true]) while converting a tool schema for the Google provider.

Common situations: Enums defined with numeric values; required lists accidentally containing objects/booleans from bad schema generation.

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 dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/1425466ba9273a06. Report an issue: GitHub.