open-telemetry / open-telemetry/opentelemetry-python

Span.set_status: a bare Status(ERROR) replaces an existing Status(ERROR, description) and drops the description

Open Beginner friendly
#5,661 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment

opentelemetry-sdk 1.44.0, CPython 3.11. Also present at main (opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py, Span.set_status).

What happened?

set_status guards two cases when it is handed a Status instance: it returns early if the span is already OK, and it returns early if the incoming status is UNSET. Nothing guards a second ERROR overwriting a first one, so self._status = status runs unconditionally and a bare Status(StatusCode.ERROR) with no description silently replaces Status(StatusCode.ERROR, "..."). The status code is unchanged, so nothing looks wrong; only the description disappears.

This is reachable without anyone doing something odd. A library sets a specific error on a span, and later generic error handling, exception bookkeeping or an instrumentation helper sets a plain ERROR on the same span. The specific message is the one that had diagnostic value, and it is the one that is lost.

Steps to reproduce

from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.trace import Status, StatusCode

span = TracerProvider().get_tracer(__name__).start_span("demo")
span.set_status(Status(StatusCode.ERROR, "connection refused to db-1"))
span.set_status(Status(StatusCode.ERROR))

print(span.status.description)

What did you expect to see?

connection refused to db-1.

What did you see instead?

None.

Suggested fix

In the isinstance(status, Status) branch, decline the assignment when the incoming status carries no description and the existing status has the same code and does have one. That keeps the first, more specific description without changing the status code, and it leaves every other transition alone, including a genuine re-description of an existing error.

It is a small change and I have it written, so a PR will follow this issue rather than wait on agreement. If maintainers would rather the precedence sat somewhere else, or would rather it not change at all, say so there and I will rework or close it.

Additional context

This surfaced from open-telemetry/opentelemetry-python-contrib#4769, where I first tried to handle it in the shared HTTP semconv helper by reading span.status before setting it. @herin049 pointed out, correctly, that the trace API does not expose a readable status on Span at all, only the SDK's ReadableSpan does, so that fix depended on an implementation detail and put precedence logic in two places that could disagree. Raising it here instead, where set_status already owns precedence.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read opentelemetry-sdk/src/opentelemetry/sdk/trace/init.py, focusing on Span.set_status and its isinstance(status, Status) branch. Run the reproduction with a described ERROR followed by a bare ERROR, then verify that the existing description remains while other status transitions are unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability-sre
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.