Compare commits

...

2 Commits

Author SHA1 Message Date
Nicholas Tindle
001ef93b37 Merge branch 'dev' into fix/open-2895-sheets-missing-credentials 2026-03-27 15:00:45 -05:00
Nicholas Tindle
cd6ddfa7e7 fix(blocks): prevent TypeError when auto_credentials field is empty
When a GoogleDriveFileField input (e.g. spreadsheet) is empty/None, the
executor skips credential injection. The block's run() is then called
without the required `credentials` kwarg, causing a TypeError wrapped as
BlockUnknownError.

Fix in two layers:
- _base.py: inject None for missing auto_credentials kwargs in _execute()
  so all GoogleDriveFileField blocks get a clean fallback
- GoogleSheetsReadBlock: accept optional credentials and guard against None

Fixes OPEN-2895

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:38:19 -05:00
3 changed files with 33 additions and 1 deletions

View File

@@ -706,6 +706,13 @@ class Block(ABC, Generic[BlockSchemaInputType, BlockSchemaOutputType]):
block_id=self.id,
)
# Ensure auto_credentials kwargs are present (even as None) so blocks
# that declare e.g. `*, credentials: GoogleCredentials` as a required
# kwarg don't crash with TypeError when the execution context didn't
# resolve credentials (e.g. the GoogleDriveFile field was empty).
for kwarg_name in self.input_schema.get_auto_credentials_fields():
kwargs.setdefault(kwarg_name, None)
# Use the validated input data
async for output_name, output_data in self.run(
self.input_schema(**{k: v for k, v in input_data.items() if v is not None}),

View File

@@ -326,11 +326,18 @@ class GoogleSheetsReadBlock(Block):
)
async def run(
self, input_data: Input, *, credentials: GoogleCredentials, **kwargs
self,
input_data: Input,
*,
credentials: GoogleCredentials | None = None,
**kwargs,
) -> BlockOutput:
if not input_data.spreadsheet:
yield "error", "No spreadsheet selected"
return
if not credentials:
yield "error", "Google credentials are required"
return
# Check if the selected file is actually a Google Sheets spreadsheet
validation_error = _validate_spreadsheet_file(input_data.spreadsheet)

View File

@@ -0,0 +1,18 @@
"""Tests for Google Sheets blocks — edge cases around credentials handling."""
import pytest
from backend.blocks.google.sheets import GoogleSheetsReadBlock
from backend.util.exceptions import BlockExecutionError
async def test_sheets_read_no_spreadsheet_yields_clean_error():
"""Executing GoogleSheetsReadBlock with no spreadsheet/credentials should
raise a clean BlockExecutionError, not a BlockUnknownError wrapping a
TypeError about a missing kwarg."""
block = GoogleSheetsReadBlock()
input_data = {"range": "Sheet1!A1:B2"} # no spreadsheet, no credentials
with pytest.raises(BlockExecutionError, match="No spreadsheet selected"):
async for _ in block.execute(input_data):
pass