locustio/locust · error · LocustError

Cannot iterate content on a response without _response attri

Error message

Cannot iterate content on a response without _response attribute

What it means

FastResponse.iter_content streams chunks from the underlying geventhttpclient response stored in self._response. If the wrapper has no _response attribute (response not backed by a real HTTP response), it raises LocustError rather than failing silently.

Source

Thrown at locust/contrib/fasthttp.py:590

    def raise_for_status(self):
        """Raise any connection errors that occurred during the request"""
        if error := getattr(self, "error", None):
            raise error

    def iter_content(self, chunk_size=1024, decode_content=True):
        """
        Simulates the `requests.Response.iter_content` method

        Used for streaming response content

        :param `chunk_size`: The size of the chunk read each time

        :param `decode_content`: Whether to decode the content (from bytes to string)

        :return: A generator that produces one chunk at a time
        """
        if not self._response:
            raise LocustError("Cannot iterate content on a response without _response attribute")

        while True:
            try:
                chunk = self._response.read(chunk_size)
                if not chunk:
                    break

                if decode_content and isinstance(chunk, bytes):
                    try:
                        chunk = chunk.decode("utf-8")
                    except UnicodeDecodeError:
                        # If decoding fails, preserve the data in byte format.
                        pass

                yield chunk
            except (HTTPConnectionClosed, ConnectionError):
                break

View on GitHub (pinned to f391a716e1)

Solutions

  1. Only call iter_content/iter_lines on responses returned from actual FastHttpSession requests
  2. If constructing FastResponse manually, set `_response` to a valid response-like object with `.read(chunk_size)`
  3. Check the response is from a successful request before streaming

Example fix

// before
resp = FastResponse()  # no _response
for line in resp.iter_lines(): ...
// after
with self.client.get("/stream", catch_response=True) as resp:
    for line in resp.iter_lines():
        ...
Defensive patterns

Strategy: type-guard

Validate before calling

def can_stream(resp):
    return getattr(resp, "_response", None) is not None

Type guard

def is_streamable(resp) -> bool:
    return getattr(resp, "_response", None) is not None and hasattr(resp._response, "read")

Try / catch

try:
    for chunk in resp.iter_content(1024):
        ...
except LocustError as e:
    logger.error("response not streamable: %s", e)

Prevention

When it happens

Trigger: Calling `iter_content()` (directly or via `iter_lines()`) on a FastResponse that lacks `_response`, e.g. a manually constructed FastResponse or one from a non-standard code path.

Common situations: Wrapping/instantiating FastResponse in custom code or tests without an underlying response; mocking responses and then calling streaming methods; using iter_lines on error-path responses.

Related errors


AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29). Data as JSON: /api/errors/0b0ded91b3e2c5bc. Report an issue: GitHub.