run-llama/llama_index · error · ValueError

Invalid additional field info: {field_info}. Must be a tuple

Error message

Invalid additional field info: {field_info}. Must be a tuple of length 2 or 3.

What it means

create_schema_model() builds a dynamic Pydantic model from a base schema plus additional field definitions. Each entry in additional_fields must be a tuple of length 2 (name, type) or length 3 (name, type, default). Any other length raises ValueError with the offending tuple echoed in the message.

Source

Thrown at llama-index-core/llama_index/core/tools/utils.py:128

                FieldInfo(
                    default=param_default,
                    description=description,
                    json_schema_extra=json_schema_extra,
                ),
            )

    additional_fields = additional_fields or []
    for field_info in additional_fields:
        if len(field_info) == 3:
            field_info = cast(Tuple[str, Type, Any], field_info)
            field_name, field_type, field_default = field_info
            fields[field_name] = (field_type, FieldInfo(default=field_default))
        elif len(field_info) == 2:
            field_info = cast(Tuple[str, Type], field_info)
            field_name, field_type = field_info
            fields[field_name] = (field_type, FieldInfo())
        else:
            raise ValueError(
                f"Invalid additional field info: {field_info}. "
                "Must be a tuple of length 2 or 3."
            )

    return create_model(name, **fields)  # type: ignore

View on GitHub (pinned to afd0fef371)

Solutions

  1. Fix each tuple to exactly (name, type) or (name, type, default).
  2. Validate programmatically before calling: assert all(len(t) in (2, 3) for t in additional_fields).
  3. When generating fields from data, normalize: if len(t) == 2, append a sensible default or None.

Example fix

# before
 fields = [('city', str, 'n/a', 'unused')]  # len 4 -> ValueError
 model = create_schema_model('Args', additional_fields=fields)

# after
 fields = [('city', str, 'n-a')]
 model = create_schema_model('Args', additional_fields=fields)
Defensive patterns

Strategy: validation

Validate before calling

def normalize_additional_fields(fields):
    out = []
    for f in fields or []:
        if len(f) == 2:
            out.append((f[0], f[1]))
        elif len(f) == 3:
            out.append((f[0], f[1], f[2]))
        else:
            raise ValueError(f'additional_fields entry must be len 2 or 3, got {f!r}')
    return out

Type guard

def is_valid_additional_fields(fields) -> bool:
    return all(isinstance(f, tuple) and len(f) in (2, 3) for f in (fields or []))

Try / catch

try:
    model = create_schema_model('Args', additional_fields=fields)
except ValueError as e:
    if 'Invalid additional field info' in str(e):
        model = create_schema_model('Args', additional_fields=normalize_additional_fields(fields))
    else:
        raise

Prevention

When it happens

Trigger: Calling create_schema_model(..., additional_fields=[('q', str, 'default', 'extra')]) (4-tuple) or [('q',)] (1-tuple); passing lists instead of tuples does NOT trigger this (len still works) but passing strings of wrong length or malformed nested data does.

Common situations: Building custom tool schemas for text-to-SQL or structured extraction; copy-paste drift when a field's default was removed but the leftover element stayed in the tuple; programmatic generation of additional_fields that sometimes emits 1- or 4-element tuples.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/72257c01b8ff18a1. Report an issue: GitHub.