apache/beam · error · PermanentException
Skip retrying because type %sstream_or_path is unsupported.
Error message
Skip retrying because type %sstream_or_path is unsupported.
What it means
stage_file_with_retry only supports seekable streams and file paths. When stream_or_path is neither (some other type), it immediately raises PermanentException stating the type is unsupported, since retries cannot be managed for it.
Solutions
- Pass a real file path string instead of in-memory content
- Wrap bytes/iterator content in a seekable object (io.BytesIO or a temp file)
- Check the supported types for stream_or_path in apiclient.py and convert before calling
Example fix
// before stage_file_with_retry(json_bytes, dest) // after import io stage_file_with_retry(io.BytesIO(json_bytes), dest) # or a temp file path
Defensive patterns
Strategy: type-guard
Validate before calling
if not (isinstance(stream_or_path, str) or (hasattr(stream_or_path, 'seekable') and stream_or_path.seekable())):
stream_or_path = io.BytesIO(tobytes(stream_or_path)) Type guard
def is_supported_stream_or_path(obj):
return isinstance(obj, str) or (hasattr(obj, 'seekable') and obj.seekable()) Try / catch
try:
stage_file_with_retry(stream_or_path, dest)
except retry.PermanentException as ex:
logger.error('unsupported staging input: %s', ex)
raise Prevention
- Only pass paths or seekable streams
- Convert bytes to BytesIO or temp files first
- Add unit tests for the staging helper with both accepted types
When it happens
Trigger: Calling stage_file_with_retry with an unsupported object type (not a seekable stream and not a path), e.g. bytes, an iterator, a custom object, or None.
Common situations: Refactored code passing downloaded content (bytes) directly instead of writing to a temp file; passing a file object that doesn't implement the stream interface; API changes in calling code.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Skip retrying because we caught exception
- A sink must inherit iobase.Sink, iobase.NativeSink, or be a…
- apache_beam.io.gcp.datastore.v1new.datastoreio.Entity…
- apache_beam.io.gcp.datastore.v1new.datastoreio.Key…
- cache_root GCS bucket path is invalid.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/aba44643c21fb72f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/runners/dataflow/internal/apiclient.py:758
self.stage_file(
gcs_or_local_path, file_name, stream, mime_type, total_size)
elif isinstance(stream_or_path, io.IOBase):
stream = stream_or_path
try:
self.stage_file(
gcs_or_local_path, file_name, stream, mime_type, total_size)
except Exception as exn:
if stream.seekable():
# reset cursor for possible retrying
stream.seek(0)
raise exn
else:
raise retry.PermanentException(
"Skip retrying because we caught exception:" +
''.join(traceback.format_exception_only(exn.__class__, exn)) +
', but the stream is not seekable.')
else:
raise retry.PermanentException(
"Skip retrying because type " + str(type(stream_or_path)) +
"stream_or_path is unsupported.")
@retry.no_retries # Using no_retries marks this as an integration point.
def create_job(self, job: Job):
"""Creates job description. May stage and/or submit for remote execution."""
self.create_job_description(job)
# Stage and submit the job when necessary
dataflow_job_file = job.options.view_as(DebugOptions).dataflow_job_file
template_location = (
job.options.view_as(GoogleCloudOptions).template_location)
if job.options.view_as(DebugOptions).lookup_experiment('upload_graph'):
self.stage_file_with_retry(
job.options.view_as(GoogleCloudOptions).staging_location,
"dataflow_graph.json",
io.BytesIO(job.json().encode('utf-8')))View on GitHub (pinned to 12126d8942)