Skip to content

Fix TraceState.update to only update already existing keys - #5543

Open
amdadulbari wants to merge 1 commit into
open-telemetry:mainfrom
amdadulbari:fix/tracestate-update-32-key-limit
Open

Fix TraceState.update to only update already existing keys#5543
amdadulbari wants to merge 1 commit into
open-telemetry:mainfrom
amdadulbari:fix/tracestate-update-32-key-limit

Conversation

@amdadulbari

@amdadulbari amdadulbari commented Aug 13, 2026

Copy link
Copy Markdown

Description

TraceState.update() can silently discard every existing entry.

update() builds a new list of entries and passes it to the TraceState constructor. When a tracestate already holds the W3C maximum of 32 members and update() is called with a new key, the new list has 33 entries; the constructor detects len(entries) > 32, logs a warning, and returns an empty TraceState. So upserting one new key into a full tracestate wipes all 32 existing key/value pairs.

This also contradicts update()'s own docstring, which states that if the pair "results in tracestate that violates tracecontext specification ... the same tracestate will be returned."

The sibling add() already guards this limit; update() did not. This change applies the same guard, but only when the key is genuinely new, so updating the value of an existing key while at capacity keeps working.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

Added two unit tests in opentelemetry-api/tests/trace/test_tracestate.py:

  • test_tracestate_update_at_capacity_new_key_preserved — updating with a new key at 32 entries preserves the existing 32 (fails before this change: len == 0).
  • test_tracestate_update_at_capacity_existing_key — updating an existing key at capacity still applies and stays within the limit.

python -m pytest opentelemetry-api/tests/trace passes (55 tests); ruff check/ruff format are clean on the changed files.

Checklist

  • Followed the style guidelines of this project (ruff).
  • Unit tests added that prove the fix is effective.
  • Changelog updated (fragment added under .changelog/).

@amdadulbari
amdadulbari requested a review from a team as a code owner August 13, 2026 04:39
@amdadulbari
amdadulbari force-pushed the fix/tracestate-update-32-key-limit branch from 264b58c to 7c471e5 Compare August 13, 2026 04:40
@xrmx xrmx moved this to Ready for review in Python PR digest Aug 13, 2026
Comment thread opentelemetry-api/src/opentelemetry/trace/span.py Outdated
@amdadulbari
amdadulbari force-pushed the fix/tracestate-update-32-key-limit branch from 7c471e5 to a4d1fe8 Compare August 14, 2026 08:39

@xrmx xrmx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit in the changelog (please also update the PR title), thanks a lot!

Comment thread .changelog/5543.fixed Outdated
@xrmx xrmx moved this from Ready for review to Approved PRs in Python PR digest Aug 14, 2026
@amdadulbari
amdadulbari force-pushed the fix/tracestate-update-32-key-limit branch from a4d1fe8 to 5466132 Compare August 14, 2026 13:36
@amdadulbari amdadulbari changed the title Fix TraceState.update dropping all entries at the 32-key limit Fix TraceState.update to only update already existing keys Aug 14, 2026
@amdadulbari

Copy link
Copy Markdown
Author

Nit in the changelog (please also update the PR title), thanks a lot!

Done, updated the changelog to your suggested wording and renamed the PR title to match. Thanks for the review!

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Aug 14, 2026

Copy link
Copy Markdown

Pull request dashboard status

Waiting on maintainers · refreshed 2026-08-14 18:36 UTC

Merge when ready.

Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

TraceState.update() builds a new entry list and passes it to the
constructor, which discards everything and returns an empty TraceState
when the list exceeds the 32-key W3C limit. As a result, upserting a new
key into a tracestate that already holds 32 entries silently wiped all 32
existing key/value pairs, contradicting update()'s documented contract
that "the same tracestate will be returned".

Guard the limit the way add() already does, but only for genuinely new
keys, so updates to existing keys at capacity keep working. Add tests for
both cases.

Signed-off-by: Md. Amdadul Bari Imad <amdadulbari@gmail.com>
@amdadulbari
amdadulbari force-pushed the fix/tracestate-update-32-key-limit branch from 49865cc to f597006 Compare August 14, 2026 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Approved PRs

Development

Successfully merging this pull request may close these issues.

2 participants