aio-libs/aiohttp · error · ValueError

Unsupported order

Error message

Unsupported order {order!r}

What it means

Raised by PayloadRegistry.register when the order argument is not one of the Order enum members (normal, try_first, try_last). Order is a str-based enum, but the registry uses identity comparison (order is Order.xxx), so passing the raw string 'normal' or an integer does not match any branch and falls through to the ValueError. This guards the internal payload-factory registration table from invalid ordering hints.

Solutions

  1. Import and pass the Order enum member: from aiohttp.payload import Order; register_payload(MyPayload, MyType, order=Order.try_first).
  2. If order comes from external data, map it explicitly: order = {'first': Order.try_first, 'last': Order.try_last}.get(raw, Order.normal).
  3. Leave order at its default (Order.normal) unless you have a specific reason to change priority.

Example fix

# before
from aiohttp.payload import register_payload
register_payload(MyPayload, MyType, order='try_first')

# after
from aiohttp.payload import register_payload, Order
register_payload(MyPayload, MyType, order=Order.try_first)
Defensive patterns

Strategy: type-guard

Validate before calling

from aiohttp.payload import Order
if not isinstance(order, Order):
    order = Order.normal
PAYLOAD_REGISTRY.register(factory, type, order=order)

Type guard

from aiohttp.payload import Order
def is_order(v) -> bool:
    return isinstance(v, Order)

Try / catch

try:
    register_payload(factory, type, order=order)
except ValueError as e:
    if 'Unsupported order' in str(e):
        register_payload(factory, type, order=Order.normal)
    else:
        raise

Prevention

When it happens

Trigger: Calling PAYLOAD_REGISTRY.register(factory, type, order='try_first') with a plain string instead of Order.try_first; calling register_payload(..., order=0) or order=None; writing a custom register call with a typo or a value imported from the wrong module.

Common situations: Third-party libraries extending aiohttp's payload registry with a custom Payload subclass; copy-pasting example code that used strings before Order was introduced; passing a value loaded from config/JSON.

Related errors


AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11). Data as JSON: /api/errors/891dedb05136bedb. Report an issue: GitHub.

Appendix: source

Thrown at aiohttp/payload.py:137

                return factory(data, *args, **kwargs)
        raise LookupError()

    def register(
        self, factory: PayloadType, type: Any, *, order: Order = Order.normal
    ) -> None:
        if order is Order.try_first:
            self._first.append((factory, type))
        elif order is Order.normal:
            self._normal.append((factory, type))
            if isinstance(type, Iterable):
                for t in type:
                    self._normal_lookup[t] = factory
            else:
                self._normal_lookup[type] = factory
        elif order is Order.try_last:
            self._last.append((factory, type))
        else:
            raise ValueError(f"Unsupported order {order!r}")


class Payload(ABC):
    _default_content_type: str = "application/octet-stream"
    _size: int | None = None
    _consumed: bool = False  # Default: payload has not been consumed yet
    _autoclose: bool = False  # Default: assume resource needs explicit closing

    def __init__(
        self,
        value: Any,
        headers: (
            CIMultiDict[str] | dict[str, str] | Iterable[tuple[str, str]] | None
        ) = None,
        content_type: None | str | _SENTINEL = sentinel,
        filename: str | None = None,
        encoding: str | None = None,
        **kwargs: Any,

View on GitHub (pinned to d041d4d0fd)