Skip to content

Bug: delete_organization raises JSONDecodeError on successful 202 response #626

@daniel-k

Description

@daniel-k

Summary

WorkOSClient.organizations.delete_organization(id) raises json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) even though the server returns 202 Accepted and the delete succeeds. The SDK attempts to JSON-parse the 202 body even though delete_organization is declared -> None and the caller discards any return value.

Environment

  • workos==6.0.4
  • Python 3.13 / 3.14
  • Linux / macOS

Reproducer

# pip install workos==6.0.4
import httpx
from unittest.mock import patch
from workos import WorkOSClient

# What the API returns for DELETE /organizations/{id}: 202 Accepted,
# non-empty body that isn't valid JSON.
fake = httpx.Response(
    status_code=202,
    content=b"\n",
    request=httpx.Request("DELETE", "https://api.workos.com/organizations/org_01TEST"),
)

client = WorkOSClient(api_key="sk_test_dummy")
http_client = next(v for v in vars(client).values() if isinstance(v, httpx.Client))

with patch.object(http_client, "request", return_value=fake):
    client.organizations.delete_organization("org_01TEST")
# → json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Same behavior observed against the real API: DELETE /organizations/{id} responds 202 Accepted (the org is deleted), but the SDK call raises.

Root cause

In workos/_base_client.py:

def _deserialize_response(self, response, model):
    if response.status_code == 204 or not response.content:
        return None
    data = cast(Dict[str, Any], response.json())
    ...

The short-circuit only covers 204 and truly-empty bytes. Any other 2xx with non-empty content forces a .json() parse, even when:

  1. The method signature declares -> None (e.g. delete_organization, delete_api_key), i.e. the SDK itself doesn't need a parsed body.
  2. No model= is passed to request(...), so whatever is parsed is discarded.

delete_api_key only works because the server happens to return 204 No Content there — it would have the same problem on any 2xx with a body.

Expected behavior

delete_organization(...) returns None on a successful 2xx response regardless of body shape.

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