Skip to content

ClientOptions causes AttributeError: 'storage' attribute missing in v2.24.0 #1306

@leplik

Description

@leplik

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When using ClientOptions with acreate_client() in supabase-py 2.24.0 (current latest), the library throws AttributeError: 'ClientOptions' object has no attribute 'storage'. This prevents users from configuring timeout parameters for Supabase clients and occurs even when passing valid parameters.

The bug was fixed in 2.23.0 but has been reintroduced in 2.24.0.

To Reproduce

Minimal reproducible code:

import asyncio
from supabase import acreate_client
from supabase.lib.client_options import ClientOptions

async def reproduce_bug():
    # Create ClientOptions with timeout parameters
    options = ClientOptions(
        postgrest_client_timeout=30,
        storage_client_timeout=30,
        function_client_timeout=30
    )

    # Attempt to create client
    url = "https://example.supabase.co"
    key = "fake-key-for-testing"

    # This throws: AttributeError: 'ClientOptions' object has no attribute 'storage'
    client = await acreate_client(url, key, options=options)

asyncio.run(reproduce_bug())

Steps:

  1. Install supabase-py 2.24.0: pip install supabase==2.24.0
  2. Run the code above
  3. Observe the AttributeError

Expected behavior

The client should be created successfully with the configured timeout values. This is the documented way to configure client options, and it works in versions 2.21.1 and 2.23.0.

Screenshots

Error in production logs:

{
  "message": "Error getting user credits: 'ClientOptions' object has no attribute 'storage'",
  "severity": "ERROR",
  "timestamp": "2025-11-08T17:46:41.122308+00:00",
  "line": 597,
  "function": "get_user_credits"
}

Version comparison:

# Version 2.21.1 (WORKS)
from supabase.lib.client_options import ClientOptions
options = ClientOptions()
print(hasattr(options, 'storage'))  # True ✓

# Version 2.24.0 (BROKEN)
from supabase.lib.client_options import ClientOptions
options = ClientOptions()
print(hasattr(options, 'storage'))  # False ✗

System information

  • OS: macOS (ARM64), Linux (tested on both)
  • Version of supabase-py: 2.24.0
  • Python version: 3.12.x, 3.13.x (tested on both)
  • Installation method: pip, uv

Additional context

Version Testing Results

Version ClientOptions with params ClientOptions no params Without ClientOptions AsyncClientOptions
2.21.1 ✓ PASS ✓ PASS ✓ PASS ✓ PASS
2.22.0 ✗ FAIL ✗ FAIL ✓ PASS ⚠ N/A
2.23.0 ✓ PASS ✓ PASS ✓ PASS ✓ PASS
2.24.0 ✗ FAIL ✗ FAIL ✓ PASS ✓ PASS

Root Cause Analysis

  1. ClientOptions.__init__() accepts storage_client_timeout parameter ✅
  2. The attribute is stored as storage_client_timeout (not storage) ✅
  3. Somewhere in the client creation code, the library tries to access options.storage
  4. This attribute doesn't exist in 2.24.0, causing the AttributeError

Workaround

Don't use ClientOptions until this is fixed:

# Instead of:
options = ClientOptions(postgrest_client_timeout=30)
client = await acreate_client(url, key, options=options)

# Use:
client = await acreate_client(url, key)  # Uses library defaults

Alternatively, use AsyncClientOptions if available:

from supabase.lib.client_options import AsyncClientOptions
options = AsyncClientOptions(postgrest_client_timeout=30)
client = await acreate_client(url, key, options=options)

Production Impact

This bug caused production failures in our environment when:

  1. Docker container installed supabase==2.24.0 (latest available)
  2. Local development used supabase==2.21.1 (from lock file)
  3. Code worked locally but crashed in production

Test Scripts

I've created comprehensive test scripts to reproduce this bug across multiple versions. Happy to share if helpful for debugging.

Related

This appears to be a regression - the same bug existed in 2.22.0, was fixed in 2.23.0, and has been reintroduced in 2.24.0. Suggests the fix from 2.23.0 was not properly carried forward.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions