open-telemetry / open-telemetry/opentelemetry-python
Confusing and delayed error "TypeError: bad argument type for built-in operation" when span name is not a string
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 19
Description
Steps to reproduce
Create a span with a non-string name, then try to encode it, e.g. with the HTTP OTLPSpanExporter. For example:
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
tracer_provider = TracerProvider()
exporter = OTLPSpanExporter()
processor = BatchSpanProcessor(exporter)
tracer_provider.add_span_processor(processor)
tracer = tracer_provider.get_tracer(__name__)
span = tracer.start_span(123)
span.end()
What is the actual behavior?
It logs:
Exception while exporting Span batch.
Traceback (most recent call last):
File "opentelemetry/sdk/trace/export/__init__.py", line 367, in _export_batch
self.span_exporter.export(self.spans_list[:idx]) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py", line 131, in export
serialized_data = encode_spans(spans).SerializeToString()
^^^^^^^^^^^^^^^^^^^
File "opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py", line 58, in encode_spans
resource_spans=_encode_resource_spans(sdk_spans)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py", line 81, in _encode_resource_spans
pb2_span = _encode_span(sdk_span)
^^^^^^^^^^^^^^^^^^^^^^
File "opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py", line 109, in _encode_span
return PB2SPan(
^^^^^^^^
TypeError: bad argument type for built-in operation
What is the expected behavior?
- Some kind of warning/exception message that's more helpful than "bad argument type for built-in operation", e.g. "span name must be a string"
- An indication of the source of the problem, e.g. a traceback pointing to the
tracer.start_span(123)line. - The span is still exported (obviously not with the original non-string span name) or at least the other spans in the batch are still exported.
Overall I suggest that the concrete opentelemetry.sdk.trace.Tracer.start_span method and/or ReadableSpan.__init__ should emit a warning if the span name is not a string and then convert the object to a string, catching any exceptions that raises. Setting an appropriate warning stacklevel is easier in Tracer.start_span, but ReadableSpan.__init__ should cover more possible code paths.
Context
While setting a non-string span name seems unusual and difficult to do accidentally, it happened in https://github.com/pydantic/logfire/issues/176 when a user called logger.exception(exc) (which is normal and OK) where logger is a standard library logging.Logger hooked up to an OTEL tracer.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Tracer.start_span and ReadableSpan.init, then follow the encoding path through opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/init.py and the HTTP exporter. Reproduce the example with OTLPSpanExporter and BatchSpanProcessor. Done means invalid span names produce a useful source-level error or warning and do not unnecessarily prevent other spans from being exported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability-sre
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100