Skip to content

vllm.entrypoints.serve.exception_handling.handlers.validation

Functions:

_format_error(err)

Render one validation error, bounded in size.

Source code in vllm/entrypoints/serve/exception_handling/handlers/validation.py
def _format_error(err: object) -> str:
    """Render one validation error, bounded in size."""
    if isinstance(err, dict):
        err = dict(err)
        if "input" in err:
            err["input"] = _summarize_error_input(err["input"])
        loc = err.get("loc")
        if isinstance(loc, (tuple, list)):
            # For a union-typed field pydantic spells every branch out in
            # `loc`, which is ~800 characters of type names per entry here.
            # `param` is already cleaned this way.
            err["loc"] = clean_loc_for_param(tuple(loc))
    text = str(err)
    if len(text) > _MAX_ERROR_CHARS:
        text = text[:_MAX_ERROR_CHARS] + "...[truncated]"
    return text

_is_internal_loc_segment(segment)

True if segment is a Pydantic-internal wrapper/union-branch marker rather than a user-meaningful field name or list index.

Source code in vllm/entrypoints/serve/exception_handling/handlers/validation.py
def _is_internal_loc_segment(segment: str) -> bool:
    """True if `segment` is a Pydantic-internal wrapper/union-branch
    marker rather than a user-meaningful field name or list index."""
    if _BRACKETED_INTERNAL_RE.search(segment):
        return True
    return segment.lower() in _INTERNAL_LOC_MARKERS

_summarize_error_input(value)

A size-bounded stand-in for a validation error's input value.

Containers are described rather than rendered: repr() of a large list materializes the whole string first, which is the cost this is meant to avoid.

Source code in vllm/entrypoints/serve/exception_handling/handlers/validation.py
def _summarize_error_input(value: object) -> object:
    """A size-bounded stand-in for a validation error's `input` value.

    Containers are described rather than rendered: `repr()` of a large
    list materializes the whole string first, which is the cost this is
    meant to avoid.
    """
    if isinstance(value, str):
        if len(value) > _MAX_ERROR_INPUT_CHARS:
            return value[:_MAX_ERROR_INPUT_CHARS] + "...[truncated]"
        return value
    if isinstance(value, (bytes, bytearray)):
        return f"<{type(value).__name__} of {len(value)} bytes>"
    if isinstance(value, (list, tuple, set, frozenset, dict)):
        return f"<{type(value).__name__} of {len(value)} items>"
    try:
        text = str(value)
    except Exception:
        # e.g. an int past `sys.get_int_max_str_digits()`.
        return f"<{type(value).__name__}>"
    if len(text) > _MAX_ERROR_INPUT_CHARS:
        return text[:_MAX_ERROR_INPUT_CHARS] + "...[truncated]"
    return text

clean_loc_for_param(loc)

Join a Pydantic error loc tuple into a clean dotted param path, dropping internal wrapper/union-branch markers that don't correspond to a real field name an API consumer would recognize.

E.g. ('body', 'function-wrap[log_extra_fields()]', 'prompt') -> "body.prompt", not "body.function-wrap[log_extra_fields()].prompt".

Source code in vllm/entrypoints/serve/exception_handling/handlers/validation.py
def clean_loc_for_param(loc: tuple) -> str:
    """Join a Pydantic error `loc` tuple into a clean dotted `param`
    path, dropping internal wrapper/union-branch markers that don't
    correspond to a real field name an API consumer would recognize.

    E.g. ('body', 'function-wrap[__log_extra_fields__()]', 'prompt')
    -> "body.prompt", not "body.function-wrap[__log_extra_fields__()].prompt".
    """
    parts = [str(p) for p in loc if not _is_internal_loc_segment(str(p))]
    if not parts:
        return ".".join(str(p) for p in loc)
    return ".".join(parts)