{"record":{"id":"2affdbd8f1208b65","repo":"apache/beam","slug":"user-provided-temp-database-id-cannot-start-with-r","errorCode":null,"errorMessage":"User provided temp database ID cannot start with %r","messagePattern":"User provided temp database ID cannot start with %r","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/spanner_wrapper.py","lineNumber":43,"sourceCode":"\nexcept ImportError:\n  spanner = None\n\n_LOGGER = logging.getLogger(__name__)\nMAX_RETRIES = 3\n\n\nclass SpannerWrapper(object):\n  TEMP_DATABASE_PREFIX = 'temp-'\n\n  def __init__(self, project_id, temp_database_id=None):\n    self._spanner_client = spanner.Client(project=project_id)\n    self._spanner_instance = self._spanner_client.instance(\"beam-test\")\n    self._test_database = None\n\n    if temp_database_id and temp_database_id.startswith(\n        self.TEMP_DATABASE_PREFIX):\n      raise ValueError(\n          'User provided temp database ID cannot start with %r' %\n          self.TEMP_DATABASE_PREFIX)\n\n    if temp_database_id is not None:\n      self._test_database = temp_database_id\n    else:\n      self._test_database = self._get_temp_database()\n\n  def _get_temp_database(self):\n    uniq_id = uuid.uuid4().hex[:10]\n    return f'{self.TEMP_DATABASE_PREFIX}{uniq_id}'\n\n  @retry.with_exponential_backoff(\n      num_retries=MAX_RETRIES,\n      retry_filter=retry.retry_on_server_errors_and_timeout_filter)\n  def _create_database(self):\n    _LOGGER.info('Creating test database: %s' % self._test_database)\n    instance = self._spanner_instance","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/spanner_wrapper.py#L25-L61","documentation":"The Beam Spanner test wrapper (spanner_wrapper.py) reserves the TEMP_DATABASE_PREFIX for databases it manages internally. If a caller supplies a temp_database_id that already starts with this reserved prefix, __init__ raises ValueError to avoid collisions between user databases and the wrapper's own temporary databases.","triggerScenarios":"Constructing the Spanner test client with temp_database_id set to a string beginning with the reserved prefix (e.g. a name auto-generated with the same convention the wrapper uses).","commonSituations":"Test harnesses reusing database names copied from a previous wrapper-created database; users unaware the prefix is reserved; looping scripts that regenerate names from wrapper output.","solutions":["Choose a temp_database_id that does not begin with the reserved prefix.","Strip the prefix from the ID before passing it in.","If you want a managed temp database, pass temp_database_id=None and let the wrapper generate one.","Check the TEMP_DATABASE_PREFIX constant on the class and assert your ID doesn't start with it before constructing."],"exampleFix":"// before\nSpannerTestClient(temp_database_id='beam-temp-mydb')\n// after\nSpannerTestClient(temp_database_id='mydb')  # no reserved prefix","handlingStrategy":"validation","validationCode":"from apache_beam.io.gcp import spanner_wrapper\nprefix = spanner_wrapper.SpannerTestClient.TEMP_DATABASE_PREFIX\nassert temp_database_id is None or not temp_database_id.startswith(prefix), temp_database_id","typeGuard":"def is_safe_db_id(x: object) -> bool:\n    return x is None or (isinstance(x, str) and not x.startswith(prefix))","tryCatchPattern":"try:\n    client = SpannerTestClient(project_id, instance_id, temp_database_id)\nexcept ValueError as e:\n    if 'cannot start with' in str(e):\n        temp_database_id = temp_database_id[len(prefix):]\n        client = SpannerTestClient(project_id, instance_id, temp_database_id)\n    else:\n        raise","preventionTips":["Never reuse names emitted by the wrapper itself","Pass None to let the wrapper generate a temp database","Keep user DB names in your own namespace","Check the TEMP_DATABASE_PREFIX constant when naming"],"tags":["google-spanner","python","naming","apache-beam"],"backgroundTag":"invalid-identifier-format","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"}