apache/beam · error · ValueError

User provided temp database ID cannot start with %r

Error message

User provided temp database ID cannot start with %r

What it means

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.

Source

Thrown at sdks/python/apache_beam/io/gcp/spanner_wrapper.py:43

except ImportError:
  spanner = None

_LOGGER = logging.getLogger(__name__)
MAX_RETRIES = 3


class SpannerWrapper(object):
  TEMP_DATABASE_PREFIX = 'temp-'

  def __init__(self, project_id, temp_database_id=None):
    self._spanner_client = spanner.Client(project=project_id)
    self._spanner_instance = self._spanner_client.instance("beam-test")
    self._test_database = None

    if temp_database_id and temp_database_id.startswith(
        self.TEMP_DATABASE_PREFIX):
      raise ValueError(
          'User provided temp database ID cannot start with %r' %
          self.TEMP_DATABASE_PREFIX)

    if temp_database_id is not None:
      self._test_database = temp_database_id
    else:
      self._test_database = self._get_temp_database()

  def _get_temp_database(self):
    uniq_id = uuid.uuid4().hex[:10]
    return f'{self.TEMP_DATABASE_PREFIX}{uniq_id}'

  @retry.with_exponential_backoff(
      num_retries=MAX_RETRIES,
      retry_filter=retry.retry_on_server_errors_and_timeout_filter)
  def _create_database(self):
    _LOGGER.info('Creating test database: %s' % self._test_database)
    instance = self._spanner_instance

View on GitHub (pinned to 12126d8942)

Solutions

  1. Choose a temp_database_id that does not begin with the reserved prefix.
  2. Strip the prefix from the ID before passing it in.
  3. If you want a managed temp database, pass temp_database_id=None and let the wrapper generate one.
  4. Check the TEMP_DATABASE_PREFIX constant on the class and assert your ID doesn't start with it before constructing.

Example fix

// before
SpannerTestClient(temp_database_id='beam-temp-mydb')
// after
SpannerTestClient(temp_database_id='mydb')  # no reserved prefix
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam.io.gcp import spanner_wrapper
prefix = spanner_wrapper.SpannerTestClient.TEMP_DATABASE_PREFIX
assert temp_database_id is None or not temp_database_id.startswith(prefix), temp_database_id

Type guard

def is_safe_db_id(x: object) -> bool:
    return x is None or (isinstance(x, str) and not x.startswith(prefix))

Try / catch

try:
    client = SpannerTestClient(project_id, instance_id, temp_database_id)
except ValueError as e:
    if 'cannot start with' in str(e):
        temp_database_id = temp_database_id[len(prefix):]
        client = SpannerTestClient(project_id, instance_id, temp_database_id)
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/2affdbd8f1208b65. Report an issue: GitHub.