apache/beam · error · ValueError

Invalid file open mode

Error message

Invalid file open mode: %s.

What it means

Raised by GcsIO.open when the `mode` argument is anything other than 'r', 'rb', 'w', or 'wb' — the GCS filesystem layer supports only those four read/write modes, unlike local files that also accept 'a', 'x', '+', etc. It fires when code passes an append, exclusive-create, or text-write mode (or a malformed mode string) to a GCS path, usually via FileSystems.open or a generic file-open wrapper.

Solutions

  1. Use only mode='r' or mode='w'.
  2. Rewrite append logic as read-all then rewrite with 'w' (GCS objects are immutable).
  3. Use mode strings without 'b' qualifiers; binary handling is internal.
  4. Add a mode check/assertion before calling open.

Example fix

// before
f = gcsio.open('gs://bucket/obj', mode='a')
// after
existing = gcsio.open('gs://bucket/obj', mode='r').read()
f = gcsio.open('gs://bucket/obj', mode='w')
f.write(existing + new_data)
Defensive patterns

Strategy: validation

Validate before calling

if mode not in ('r', 'w'):
    raise ValueError(f'unsupported mode for GcsIO.open: {mode!r}')

Type guard

def is_valid_gcs_mode(mode):
    return mode in ('r', 'w')

Try / catch

try:
    f = gcsio.open(path, mode)
except ValueError as e:
    logging.error('open failed: %s', e)
    raise

Prevention

When it happens

Trigger: Calling gcsio.open(path, mode) with mode values other than 'r'/'w' (e.g. 'a' to append, 'r+', or an empty mode string).

Common situations: Porting code written for local files using append or read-write modes; passing a mode variable defaulted incorrectly; assuming GCSIO supports the full built-in open() mode set.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/io/gcp/gcsio.py:306

    bucket_name, blob_name = parse_gcs_path(filename)
    bucket = self.client.bucket(bucket_name)

    if mode == 'r' or mode == 'rb':
      blob = bucket.blob(blob_name)
      return BeamBlobReader(
          blob,
          chunk_size=read_buffer_size,
          enable_read_bucket_metric=self.enable_read_bucket_metric,
          retry=self._storage_client_retry)
    elif mode == 'w' or mode == 'wb':
      blob = bucket.blob(blob_name)
      return BeamBlobWriter(
          blob,
          mime_type,
          enable_write_bucket_metric=self.enable_write_bucket_metric,
          retry=self._storage_client_retry)
    else:
      raise ValueError('Invalid file open mode: %s.' % mode)

  def delete(self, path, recursive=False):
    """Deletes the object at the given GCS path.

    If the path is a directory (prefix), it deletes all blobs under that prefix
    when recursive=True.

    Args:
      path: GCS file path pattern in the form gs://<bucket>/<name>.
      recursive (bool, optional): If True, deletes all objects under the prefix
          when the path is a directory (default: False).
    """
    bucket_name, blob_name = parse_gcs_path(path)
    bucket = self.client.bucket(bucket_name)
    if recursive:
      # List all blobs under the prefix.
      blobs_to_delete = bucket.list_blobs(
          prefix=blob_name, retry=self._storage_client_retry)

View on GitHub (pinned to 12126d8942)