Skip to content

fix(storage): raise StorageApiError when a bucket error body is unrecognized - #1574

Open
tushardev-365 wants to merge 1 commit into
supabase:mainfrom
tushardev-365:fix/storage-bucket-error-parsing
Open

fix(storage): raise StorageApiError when a bucket error body is unrecognized#1574
tushardev-365 wants to merge 1 commit into
supabase:mainfrom
tushardev-365:fix/storage-bucket-error-parsing

Conversation

@tushardev-365

Copy link
Copy Markdown
Contributor

What

StorageBucketAPI._request indexed the parsed error body directly:

except HTTPStatusError as exc:
    resp = exc.response.json()
    raise StorageApiError(resp["message"], resp["error"], resp["statusCode"]) from exc

So a storage error whose JSON body is missing any of message / error / statusCode came back as a bare KeyError, and a body that isn't JSON at all (an HTML page from a proxy or gateway) came back as a JSONDecodeError. Either way the caller lost the real status and body and got an opaque exception instead of StorageApiError — on the one path where the message matters most. This affects every bucket operation: list_buckets, get_bucket, create_bucket, update_bucket, empty_bucket, delete_bucket.

Fix

Wrap the lookup and fall back to StorageApiError carrying the raw response text, mirroring the shape file_api._request already uses and the ValidationError fallback request.py uses for vector buckets.

Tests

Two new cases per flavour (async + sync), asserting StorageApiError rather than the leaked exception:

  • error body missing the expected keys
  • error body that isn't JSON

Reverting only the source change makes all four fail with the raw KeyError / JSONDecodeError; with the fix the bucket suite is 28 passed.

Note

#1563 reports this same class of bug in file_api._request (its recovery path reaches for resp.text on a dict), and there are already PRs open for that file. This PR is the bucket API only, which is a separate _request with no recovery path at all — so the two don't overlap.

_sync is generated, so the change was made in _async and regenerated with make build-sync; only the bucket files are included here.

…ognized

StorageBucketAPI._request indexed the parsed error body directly:

    resp = exc.response.json()
    raise StorageApiError(resp["message"], resp["error"], resp["statusCode"])

A storage error whose JSON body is missing any of those keys therefore
surfaced as a bare KeyError, and a body that is not JSON at all (an HTML
page from a proxy or gateway, say) surfaced as a JSONDecodeError. Either
way the caller lost the real status and body and got an opaque exception
instead of StorageApiError, on the path where the message matters most.

Wrap the lookup and fall back to StorageApiError carrying the raw
response text, mirroring the shape file_api._request already uses and the
ValidationError fallback in request.py for vector buckets.
@tushardev-365
tushardev-365 requested review from a team and o-santi as code owners August 15, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant