apache/beam · error · TypeError
%s: table must be of type string; got a callable instead
Error message
%s: table must be of type string; got a callable instead
What it means
In the BEAM_ROW output path (bigquery.py:3123), the table must be a literal string so the schema can be fetched from the BigQuery API at pipeline-construction time. A callable table (e.g. a lambda or function returning the table name) cannot be resolved then, so TypeError is raised.
Source
Thrown at sdks/python/apache_beam/io/gcp/bigquery.py:3123
def _expand_output_type(self, output_pcollection):
if self.output_type == 'PYTHON_DICT' or self.output_type is None:
return output_pcollection
elif self.output_type == 'BEAM_ROW':
if self._kwargs.get('query', None) is not None:
user_schema = bigquery_tools.get_dict_table_schema(
self.query_output_schema)
return output_pcollection | bigquery_schema_tools.convert_to_usertype(
user_schema, self._kwargs.get('selected_fields', None))
table_details = bigquery_tools.parse_table_reference(
table=self._kwargs.get("table", None),
dataset=self._kwargs.get("dataset", None),
project=self._kwargs.get("project", None))
if isinstance(self._kwargs['table'], ValueProvider):
raise TypeError(
'%s: table must be of type string'
'; got ValueProvider instead' % self.__class__.__name__)
elif callable(self._kwargs['table']):
raise TypeError(
'%s: table must be of type string'
'; got a callable instead' % self.__class__.__name__)
return output_pcollection | bigquery_schema_tools.convert_to_usertype(
bigquery_tools.BigQueryWrapper().get_table(
project_id=table_details.projectId,
dataset_id=table_details.datasetId,
table_id=table_details.tableId).schema,
self._kwargs.get('selected_fields', None))
else:
raise ValueError(
'The output type from BigQuery must be either PYTHON_DICT '
'or BEAM_ROW.')
def _expand_export(self, pcoll):
# TODO(https://github.com/apache/beam/issues/20683): Make ReadFromBQ rely
# on ReadAllFromBQ implementation.
temp_location = pcoll.pipeline.options.view_as(
GoogleCloudOptions).temp_locationView on GitHub (pinned to 12126d8942)
Solutions
- Pass the table name as a plain string like 'project:dataset.table' or 'dataset.table'
- Compute the value before building the pipeline and pass the resulting string
- If the table must be dynamic, switch output_type to PYTHON_DICT
Example fix
// before
ReadFromBigQuery(table=lambda: f'{p}:{d}.{t}', output_type='BEAM_ROW')
// after
ReadFromBigQuery(table=f'{p}:{d}.{t}', output_type='BEAM_ROW') Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(table, str) and not callable(table)
Type guard
def is_static_table(table):
return isinstance(table, str) and not callable(table) Prevention
- Never wrap table names in lambdas
- Compute dynamic table names eagerly before pipeline construction
- Keep table-name construction in plain string code
When it happens
Trigger: Passing table=lambda: 'project:dataset.table' or any callable while output_type='BEAM_ROW'; passing a bound method or class property object as table.
Common situations: Users wrapping the table name in a helper to compute it from options; misusing ValueProvider-style APIs by passing a function; code refactors where the table was made dynamic.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- %s: gcs_location must be of type string or ValueProvider; go
- Table schema must be of the type bigquery.TableSchema
- Unexpected schema argument: %s.
- Unexpected keyword arguments: {', '.join(kwargs)}
- Unable to convert objects of type %s to a PCollection
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4b3a8120cdf267f4.
Report an issue: GitHub.