Skip to content

JSONDecodeError when receiving 204 No Content response (4.0.8) #30

@prouzet-pass

Description

@prouzet-pass

Hello,

When migrating to v4, we are experiencing issues when receiving responses with HTTP status code 204: brevo-python library tries to decodes JSON from a body which has... no content (as expected with status code 204). This leads to an unexpected ApiError.

The following minimal example reproduces the issue. Contact is well created then updated on Brevo side (CRM shows that the value for attribute USER_ID is 456 after execution), so I guess that no exception should be raised.

import time

import brevo

API_KEY = "xkeysib-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx"

email = f"bug+{int(time.time())}@example.com"

client = brevo.Brevo(api_key=API_KEY)
response = client.contacts.create_contact(email=email, attributes={"USER_ID": 123}, update_enabled=True)
print(response)
response = client.contacts.create_contact(email=email, attributes={"USER_ID": 456}, update_enabled=True)
print(response)

Here is the full output with stacktrace when running the script above:

$ python /home/patrick/tmp/bug.py
id=207952
Traceback (most recent call last):
  File "/home/patrick/.cache/pypoetry/virtualenvs/pcapi-KcUJqeq--py3.13/lib/python3.13/site-packages/brevo/contacts/raw_client.py", line 260, in create_contact
    object_=_response.json(),
            ~~~~~~~~~~~~~~^^
  File "/home/patrick/.cache/pypoetry/virtualenvs/pcapi-KcUJqeq--py3.13/lib/python3.13/site-packages/httpx/_models.py", line 832, in json
    return jsonlib.loads(self.content, **kwargs)
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.13/json/__init__.py", line 352, in loads
    return _default_decoder.decode(s)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "/usr/lib/python3.13/json/decoder.py", line 345, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.13/json/decoder.py", line 363, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/patrick/tmp/bug.py", line 12, in <module>
    response = client.contacts.create_contact(email=email, attributes={"USER_ID": 456}, update_enabled=True)
  File "/home/patrick/.cache/pypoetry/virtualenvs/pcapi-KcUJqeq--py3.13/lib/python3.13/site-packages/brevo/contacts/client.py", line 203, in create_contact
    _response = self._raw_client.create_contact(
        attributes=attributes,
    ...<7 lines>...
        request_options=request_options,
    )
  File "/home/patrick/.cache/pypoetry/virtualenvs/pcapi-KcUJqeq--py3.13/lib/python3.13/site-packages/brevo/contacts/raw_client.py", line 288, in create_contact
    raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
brevo.core.api_error.ApiError: headers: {'date': 'Fri, 27 Mar 2026 11:21:54 GMT', 'content-type': 'text/plain; charset=utf-8', 'connection': 'keep-alive', 'cf-ray': '9e2e03a08d5bef8d-WAW', 'x-envoy-upstream-service-time': '197', 'access-control-allow-credentials': 'true', 'sib-request-id': '30e941c6-391e-976e-aa8a-3299bbdb07d1', 'access-control-allow-origin': '*', 'access-control-allow-headers': '*', 'access-control-allow-methods': 'PUT, POST, GET, DELETE, PATCH, OPTIONS', 'x-sib-ratelimit-limit': '20', 'x-sib-ratelimit-remaining': '19', 'x-sib-ratelimit-reset': '1', 'cf-cache-status': 'DYNAMIC', 'server': 'cloudflare'}, status_code: 204, body:                                                          

Case of status code 204 No Content should probably be excluded from the block which reads content as json here: https://github.com/getbrevo/brevo-python/blob/v4.0.8/src/brevo/contacts/raw_client.py#L255 (and probably also in other modules).

My environment:

  • python 3.13
  • poetry 2.2.1
  • brevo-python 4.0.8
  • httpx 0.28.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions