Skip to content

ValidationError when creating signed URLs for non-existent files #1455

@NafeesMadni

Description

@NafeesMadni

Describe the bug

  • What I am doing: I am using the create_signed_urls function to generate signed URLs for files in a Supabase storage bucket.
  • What I expect is: If a specified file path does not exist in the bucket, I expect the function to gracefully handle the API response (which may return None for the signedURL for that file) without raising a ValidationError.
  • What actually happening is: When a file path does not exist, the create_signed_urls function raises a pydantic_core._pydantic_core.ValidationError because the Pydantic model SignedUrlsJsonItem expects a string type for signedURL, but the API returns None (null) in such cases.

Reproduction

When calling create_signed_urls with a list of file paths, if one of the files does not exist, the Supabase API returns a response similar to this:

[
    {
        "error": null,
       "path": "existing_file.txt",
       "signedURL": "/object/sign/fileio/existing_file.txt?token=..."
    },
    {
       "error": "Either the object does not exist or you do not have access to it",
       "path": "non_existent_file.txt",
       "signedURL": null
   }
]

The SignedUrlsJsonResponse in the current SDK is defined using SignedUrlsJsonItem, which currently expects signedURL to be a string:

class SignedUrlsJsonItem(BaseModel, extra="ignore"):
   error: Optional[str]
   path: str
   signedURL: str # This is the problematic field, should be Optional[str]
   
SignedUrlsJsonResponse = TypeAdapter(list[SignedUrlsJsonItem])

Because the SDK definition requires signedURL to be a string, it fails validation when it receives null from the API, leading to the

pydantic_core._pydantic_core.ValidationError: 1 validation error for list[SignedUrlsJsonItem] 1.signedURL Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]

Here's an example of how to trigger this (assuming non_existent_file.txt does not exist):

# Assuming you have a client and bucket initialized
# from supabase import create_client, Client

# url: str = "YOUR_SUPABASE_URL"
# key: str = "YOUR_SUPABASE_ANON_KEY"
# supabase: Client = create_client(url, key)
# bucket_name = "your-bucket-name"

# Example call that might trigger the error if 'non_existent_file.txt' does not exist
# The actual error occurs within the SDK's internal processing of the API response.
try:
   # Example: a list of file paths, where one or more might not exist
   paths_to_sign = ["existing_file.txt", "non_existent_file.txt"]
   expires_in_seconds = 3600
   
   # This call would fail if 'non_existent_file.txt' does not exist
   signed_urls = supabase.storage.from_(bucket_name).create_signed_urls(
       paths_to_sign, expires_in_seconds
   )
   print(signed_urls)
except Exception as e:
   print(f"An error occurred: {e}")
   # Expected to catch pydantic_core._pydantic_core.ValidationError

Steps to reproduce

No response

Library affected

storage3

Library version

supabase 2.28.3

Python version

Python 3.13.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions