dagger/dagger · error

properties must be a map, got %T

Error message

properties must be a map, got %T

What it means

bbiPropertiesToGenaiSchemas asserts that the "properties" value is a map[string]any mapping property names to schema objects. This error fires when properties is any other type (list, string, null explicitly), before per-property processing begins.

Source

Thrown at core/llm_google.go:637

			}
			schema.Required = required
		case "enum":
			enum, err := toStringSlice(param)
			if err != nil {
				return nil, fmt.Errorf("failed to convert enum field: %w", err)
			}
			schema.Enum = enum
			schema.Format = "enum"
		}
	}

	return schema, nil
}

func bbiPropertiesToGenaiSchemas(param any) (map[string]*genai.Schema, error) {
	props, ok := param.(map[string]any)
	if !ok {
		return nil, fmt.Errorf("properties must be a map, got %T", param)
	}
	schemas := map[string]*genai.Schema{}
	for propKey, propParam := range props {
		propParamMap, ok := propParam.(map[string]any)
		if !ok {
			return nil, fmt.Errorf("property %s must be a map, got %T", propKey, propParam)
		}
		propSchema, err := bbiSchemaToGenaiSchema(propParamMap)
		if err != nil {
			return nil, fmt.Errorf("failed to convert property %s: %w", propKey, err)
		}
		schemas[propKey] = propSchema
	}
	return schemas, nil
}

func toSchemaMaps(val any) ([]map[string]any, error) {
	switch x := val.(type) {

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Make properties an object mapping property names to schema objects
  2. Remove the properties key entirely if the parameter takes no properties
  3. Pre-validate schemas with a JSON Schema validator before registering tools

Example fix

// before
"properties": ["width", "height"]
// after
"properties": {"width": {"type": "number"}, "height": {"type": "number"}}
Defensive patterns

Strategy: type-guard

Validate before calling

func checkProperties(s map[string]any) error {
    p, ok := s["properties"]
    if !ok { return nil }
    if _, isMap := p.(map[string]any); !isMap {
        return fmt.Errorf("properties must be an object, got %T", p)
    }
    return nil
}

Type guard

func isPropsMap(v any) (map[string]any, bool) {
    m, ok := v.(map[string]any)
    return m, ok
}

Try / catch

props, err := bbiPropertiesToGenaiSchemas(param)
if err != nil {
    if strings.HasPrefix(err.Error(), "properties must be a map") {
        return fmt.Errorf("tool schema properties invalid: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Tool schema with properties as a non-map, e.g. "properties": ["a","b"] or "properties": "none", passed from bbiSchemaToGenaiSchema's "properties" case during convertToolsToGenai.

Common situations: Schemas from tooling that emits properties as ordered lists; hand-written maps where properties was set to a placeholder; JSON Schema variants (like tuple-only schemas) that omit object properties.

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/6a7f736679caa4e5. Report an issue: GitHub.