{"record":{"id":"4b3a8120cdf267f4","repo":"apache/beam","slug":"s-table-must-be-of-type-string-got-a-callable-instead","errorCode":null,"errorMessage":"%s: table must be of type string; got a callable instead","messagePattern":"(.+?): table must be of type string; got a callable instead","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/bigquery.py","lineNumber":3123,"sourceCode":"  def _expand_output_type(self, output_pcollection):\n    if self.output_type == 'PYTHON_DICT' or self.output_type is None:\n      return output_pcollection\n    elif self.output_type == 'BEAM_ROW':\n      if self._kwargs.get('query', None) is not None:\n        user_schema = bigquery_tools.get_dict_table_schema(\n            self.query_output_schema)\n        return output_pcollection | bigquery_schema_tools.convert_to_usertype(\n            user_schema, self._kwargs.get('selected_fields', None))\n      table_details = bigquery_tools.parse_table_reference(\n          table=self._kwargs.get(\"table\", None),\n          dataset=self._kwargs.get(\"dataset\", None),\n          project=self._kwargs.get(\"project\", None))\n      if isinstance(self._kwargs['table'], ValueProvider):\n        raise TypeError(\n            '%s: table must be of type string'\n            '; got ValueProvider instead' % self.__class__.__name__)\n      elif callable(self._kwargs['table']):\n        raise TypeError(\n            '%s: table must be of type string'\n            '; got a callable instead' % self.__class__.__name__)\n      return output_pcollection | bigquery_schema_tools.convert_to_usertype(\n          bigquery_tools.BigQueryWrapper().get_table(\n              project_id=table_details.projectId,\n              dataset_id=table_details.datasetId,\n              table_id=table_details.tableId).schema,\n          self._kwargs.get('selected_fields', None))\n    else:\n      raise ValueError(\n          'The output type from BigQuery must be either PYTHON_DICT '\n          'or BEAM_ROW.')\n\n  def _expand_export(self, pcoll):\n    # TODO(https://github.com/apache/beam/issues/20683): Make ReadFromBQ rely\n    # on ReadAllFromBQ implementation.\n    temp_location = pcoll.pipeline.options.view_as(\n        GoogleCloudOptions).temp_location","sourceCodeStart":3105,"sourceCodeEnd":3141,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/bigquery.py#L3105-L3141","documentation":"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.","triggerScenarios":"Passing table=lambda: 'project:dataset.table' or any callable while output_type='BEAM_ROW'; passing a bound method or class property object as table.","commonSituations":"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.","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"],"exampleFix":"// before\nReadFromBigQuery(table=lambda: f'{p}:{d}.{t}', output_type='BEAM_ROW')\n// after\nReadFromBigQuery(table=f'{p}:{d}.{t}', output_type='BEAM_ROW')","handlingStrategy":"type-guard","validationCode":"assert isinstance(table, str) and not callable(table)","typeGuard":"def is_static_table(table):\n    return isinstance(table, str) and not callable(table)","tryCatchPattern":null,"preventionTips":["Never wrap table names in lambdas","Compute dynamic table names eagerly before pipeline construction","Keep table-name construction in plain string code"],"tags":["python","apache-beam","bigquery","type-error"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}