locustio/locust · error · LocustError

If you want to change the state of the request using .succes

Error message

If you want to change the state of the request using .success() or .failure(), you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses

What it means

Locust monkey-patches requests.Response.success/failure to raise LocustError with guidance, so calls on a plain (non-catch_response) requests Response fail fast. This catches the common mistake of calling success()/failure() on a Response returned without catch_response=True, where manual marking is unsupported.

Source

Thrown at locust/clients.py:539

                conn.cert_file = cert
                conn.key_file = None
            if conn.cert_file and not os.path.exists(conn.cert_file):
                raise OSError(f"Could not find the TLS certificate file, invalid path: {conn.cert_file}")
            if conn.key_file and not os.path.exists(conn.key_file):
                raise OSError(f"Could not find the TLS key file, invalid path: {conn.key_file}")

    def build_connection_pool_key_attributes(self, request, verify, cert=None):
        host_params, pool_kwargs = super().build_connection_pool_key_attributes(request, verify, cert)

        if requests_version >= (2, 32, 5) and verify is True:
            pool_kwargs["ssl_context"] = _preloaded_ssl_context

        return host_params, pool_kwargs


# Monkey patch Response class to give some guidance
def _missing_catch_response_True(self, *_args, **_kwargs):
    raise LocustError(
        "If you want to change the state of the request using .success() or .failure(), you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
    )


Response.success = _missing_catch_response_True  # type: ignore[attr-defined]
Response.failure = _missing_catch_response_True  # type: ignore[attr-defined]

View on GitHub (pinned to f391a716e1)

Solutions

  1. Add `catch_response=True` to the request call
  2. Keep validation logic only on requests created with catch_response=True
  3. Use `response.raise_for_status()` or status_code checks without manual marking when catch_response is not needed

Example fix

// before
response = self.client.get("/api")
if response.status_code == 200:
    response.success()  # raises
// after
with self.client.get("/api", catch_response=True) as response:
    if response.status_code == 200:
        response.success()
Defensive patterns

Strategy: validation

Validate before calling

def mark_success(client, url, **kw):
    kw.setdefault("catch_response", True)
    with client.get(url, **kw) as resp:
        resp.success()

Type guard

null

Try / catch

try:
    with client.get(url, catch_response=True) as resp:
        resp.success()
except LocustError as e:
    logger.warning("catch_response missing: %s", e)

Prevention

When it happens

Trigger: Calling `.success()` or `.failure()` on the Response from `self.client.get(...)` (HttpSession) when `catch_response=True` was not passed.

Common situations: Forgetting catch_response=True when adding validation; IDE autocomplete suggesting success()/failure() on requests.Response; sharing validation code between catch and non-catch calls.

Related errors


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