Skip to content

Next Python SDK major - #5005

Draft
sentrivana wants to merge 448 commits into
masterfrom
major/3.0
Draft

sentrivana wants to merge 448 commits into
masterfrom
major/3.0

Conversation

@sentrivana

@sentrivana sentrivana commented Oct 24, 2025 •

Copy link
Copy Markdown
Collaborator

We're preparing our next major on this branch.

The project is tracked in Linear. If you don't have access, we'll try to tag issues belonging to the project with the SDK 3.0 label on GitHub so that you can follow along.

Notable changes

  • Transaction-based tracing will be removed. Span streaming will be the default tracing model.
  • Python 3.6 support will be removed.

Context

You might have read this announcement about us discontinuing work on a 3.0. This is referring to the work done on the potel-base branch, which included two types of changes: a huge refactor of our tracing code on the one hand, and various unrelated changes, improvements and fixes on the other. We're dropping the huge refactor part, and only porting the rest, to a new branch and eventually a new 3.0 release.

@codecov

codecov Bot commented Oct 24, 2025 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.76%. Comparing base (14aff96) to head (d864ba0).
⚠️ Report is 4 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #5005       +/-   ##
===========================================
+ Coverage   70.55%   83.76%   +13.21%     
===========================================
  Files         180      180               
  Lines       18077    18080        +3     
  Branches     3008     3009        +1     
===========================================
+ Hits        12754    15145     +2391     
+ Misses       4432     1943     -2489     
- Partials      891      992      +101     
Files with missing lines Coverage Δ
sentry_sdk/integrations/__init__.py 88.42% <100.00%> (+0.37%) ⬆️

... and 61 files with indirect coverage changes

@github-actions

github-actions Bot commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Results 📊

✅ 57523 passed | ⏭️ 2979 skipped | Total: 60502 | Pass Rate: 95.08% | Execution Time: 160m 16s

All tests are passing successfully.

✅ Patch coverage is 88.46% (2851 of 3223 changed executable lines covered; target 80%).
Project statement coverage is 90.17% (down 0.12 percentage points from base (63707d7) to head (c15fd9b)).

Changed files with executable lines (143)
File Patch coverage Changed executable lines
sentry_sdk/integrations/aws_lambda/_handler.py 19.10% 17/89 covered; missed: 43, 45, 46, 59, 60, 62, 63, 65, 66, 67, 69, 70, 72, 76, 78, 79, 80, 81, 82, 83, 91, 95, 99, 107, 109, 112, 113, 115, 116, 117, 118, 119, 120, 121, 125, 126, 127, 131, 132, 133, 134, 135, 139, 140, 144, 145, 146, 147, 149, 154, 156, 168, 169, 170, 171, 172, 173, 174, 176, 190, 191, 192, 197, 198, 199, 200, 201, 205, 206, 208, 209, 211
sentry_sdk/integrations/aws_lambda/_runtime.py 22.00% 11/50 covered; missed: 23, 25, 26, 28, 29, 31, 32, 33, 37, 41, 42, 43, 47, 68, 70, 72, 76, 77, 78, 79, 82, 101, 102, 103, 104, 106, 109, 110, 112, 115, 117, 121, 122, 123, 124, 125, 126, 127, 138
sentry_sdk/integrations/aws_lambda/_request.py 69.86% 51/73 covered; missed: 19, 25, 27, 28, 29, 31, 32, 33, 35, 68, 76, 77, 78, 82, 83, 91, 92, 93, 97, 98, 101, 120; partial branches: 18, 22, 67, 75, 88, 90, 95, 96, 119
sentry_sdk/integrations/langchain.py 90.26% 139/154 covered; missed: 237, 274, 388, 405, 414, 492, 501, 507, 522, 528, 548, 591, 592, 598, 1244; partial branches: 236, 273, 285, 387, 404, 413, 491, 500, 506, 521, 527, 547
sentry_sdk/integrations/ray.py 33.33% 11/33 covered; missed: 92, 94, 95, 104, 105, 106, 107, 108, 109, 111, 130, 134, 135, 138, 139, 140, 141, 143, 160, 161, 162, 163; partial branches: 129
sentry_sdk/integrations/aws_lambda/init.py 36.36% 12/33 covered; missed: 24, 28, 29, 30, 34, 36, 37, 41, 43, 47, 49, 52, 53, 57, 62, 63, 64, 65, 67, 69, 74
sentry_sdk/integrations/mcp.py 93.55% 87/93 covered; missed: 279, 283, 355, 359, 403, 405; partial branches: 278, 282, 288, 354, 358, 366, 371, 386, 389, 393, 395, 398, 447, 449
sentry_sdk/integrations/anthropic.py 76.92% 30/39 covered; missed: 459, 461, 463, 467, 472, 695, 785, 994, 1096; partial branches: 471, 694, 784, 993, 1095
sentry_sdk/integrations/google_genai/init.py 80.65% 50/62 covered; missed: 76, 106, 139, 140, 142, 144, 170, 243, 262, 263, 264, 265; partial branches: 75, 242
sentry_sdk/integrations/socket.py 59.09% 13/22 covered; missed: 59, 96, 107, 108, 114, 115, 116, 117, 118; partial branches: 58, 68, 95, 105, 112
sentry_sdk/tracing_utils.py 73.33% 33/45 covered; missed: 193, 194, 195, 200, 201, 202, 203, 205, 206, 207, 209, 211; partial branches: 152, 337
sentry_sdk/integrations/gcp.py 7.14% 1/14 covered; missed: 88, 89, 100, 104, 105, 131, 132, 134, 225, 226, 230, 231, 237
sentry_sdk/integrations/openai_agents/patches/runner.py 80.95% 34/42 covered; missed: 152, 173, 178, 179, 196, 201, 202, 203; partial branches: 151, 164, 169, 193
sentry_sdk/integrations/litestar.py 85.00% 34/40 covered; missed: 169, 184, 186, 204, 206, 272; partial branches: 168, 183, 185, 203, 205
sentry_sdk/integrations/asyncpg.py 86.21% 25/29 covered; missed: 216, 217, 244, 245; partial branches: 113, 212, 240, 247, 250
sentry_sdk/integrations/pydantic_ai/spans/ai_client.py 86.11% 31/36 covered; missed: 330, 331, 332, 333, 334; partial branches: 295, 300, 305, 323
sentry_sdk/integrations/mistral.py 92.31% 48/52 covered; missed: 321, 325, 441, 445; partial branches: 320, 324, 440, 444
sentry_sdk/integrations/openai_agents/spans/ai_client.py 87.10% 27/31 covered; missed: 227, 228, 239, 255; partial branches: 225, 230, 238, 254
sentry_sdk/integrations/otlp.py 87.10% 27/31 covered; missed: 154, 158, 180, 219; partial branches: 149, 153, 157, 174
sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py 100.00% 41/41 covered; partial branches: 65, 69, 77, 95, 103, 111, 113, 121
sentry_sdk/integrations/openai_agents/patches/agent_run.py 58.33% 7/12 covered; missed: 60, 225, 232, 254, 263; partial branches: 104, 182
sentry_sdk/integrations/quart.py 86.84% 33/38 covered; missed: 105, 107, 108, 148, 149; partial branches: 190, 200
sentry_sdk/integrations/aiohttp.py 95.45% 63/66 covered; missed: 331, 332, 333; partial branches: 169, 263, 330
sentry_sdk/integrations/asgi.py 86.49% 32/37 covered; missed: 244, 246, 248, 249, 254; partial branches: 230
sentry_sdk/integrations/django/init.py 94.92% 56/59 covered; missed: 805, 824, 900; partial branches: 590, 804, 823
sentry_sdk/integrations/openai.py 96.84% 92/95 covered; missed: 413, 524, 794; partial branches: 585, 604, 793
sentry_sdk/integrations/starlette.py 93.48% 43/46 covered; missed: 109, 165, 811; partial branches: 164, 550, 748
sentry_sdk/integrations/typesafe.py 90.00% 18/20 covered; missed: 265, 349; partial branches: 230, 264, 314, 348
sentry_sdk/integrations/sqlalchemy.py 86.67% 13/15 covered; missed: 169, 173; partial branches: 82, 150, 164
sentry_sdk/_init_implementation.py 89.47% 17/19 covered; missed: 21, 33; partial branches: 20, 32
sentry_sdk/integrations/aiomysql.py 100.00% 21/21 covered; partial branches: 98, 102, 146, 150
sentry_sdk/integrations/chalice.py 94.29% 33/35 covered; missed: 97, 141; partial branches: 96, 100
sentry_sdk/integrations/cohere.py 81.82% 18/22 covered; missed: 144, 149, 158, 260
sentry_sdk/integrations/django/caching.py 97.37% 37/38 covered; missed: 62; partial branches: 61, 81, 108
sentry_sdk/integrations/django/templates.py 77.78% 7/9 covered; missed: 58, 92; partial branches: 57, 91
sentry_sdk/integrations/django/views.py 84.62% 11/13 covered; missed: 25, 75; partial branches: 24, 74
sentry_sdk/integrations/langgraph.py 97.37% 37/38 covered; missed: 275; partial branches: 118, 137, 272
sentry_sdk/integrations/openai_agents/init.py 96.77% 30/31 covered; missed: 133; partial branches: 90, 116, 126
sentry_sdk/client.py 92.31% 24/26 covered; missed: 420, 421; partial branches: 838
sentry_sdk/integrations/boto3/_utils.py 95.00% 19/20 covered; missed: 33; partial branches: 32, 36
sentry_sdk/integrations/flask.py 66.67% 6/9 covered; missed: 48, 142, 143
sentry_sdk/integrations/google_genai/utils.py 88.46% 23/26 covered; missed: 711, 720, 909
sentry_sdk/integrations/grpc/aio/client.py 87.50% 14/16 covered; missed: 90, 93; partial branches: 89
sentry_sdk/integrations/grpc/client.py 85.71% 12/14 covered; missed: 64, 67; partial branches: 63
sentry_sdk/integrations/starlite.py 87.50% 14/16 covered; missed: 155, 247; partial branches: 154
sentry_sdk/scope.py 100.00% 67/67 covered; partial branches: 764, 1494, 1536
sentry_sdk/data_collection.py 83.33% 5/6 covered; missed: 260; partial branches: 259
sentry_sdk/integrations/celery/init.py 100.00% 37/37 covered; partial branches: 105, 365
sentry_sdk/integrations/django/asgi.py 90.00% 9/10 covered; missed: 181; partial branches: 180
sentry_sdk/integrations/django/middleware.py 80.00% 4/5 covered; missed: 80; partial branches: 79
sentry_sdk/integrations/django/transactions.py 71.43% 5/7 covered; missed: 16, 17
sentry_sdk/integrations/google_genai/streaming.py 84.62% 11/13 covered; missed: 115, 119
sentry_sdk/integrations/grpc/server.py 66.67% 4/6 covered; missed: 62, 63
sentry_sdk/integrations/huggingface_hub.py 93.33% 28/30 covered; missed: 232, 427
sentry_sdk/integrations/pure_eval.py 33.33% 1/3 covered; missed: 24, 30
sentry_sdk/integrations/pyramid.py 86.67% 13/15 covered; missed: 78, 79
sentry_sdk/integrations/pyreqwest.py 100.00% 19/19 covered; partial branches: 139, 163
sentry_sdk/integrations/redis/modules/queries.py 100.00% 10/10 covered; partial branches: 55, 58
sentry_sdk/integrations/strawberry.py 97.67% 42/43 covered; missed: 271; partial branches: 270
sentry_sdk/integrations/tornado.py 100.00% 46/46 covered; partial branches: 134, 136
sentry_sdk/traces.py 96.49% 55/57 covered; missed: 293, 678
sentry_sdk/utils.py 95.12% 39/41 covered; missed: 1417, 1997
sentry_sdk/api.py 91.67% 11/12 covered; missed: 178
sentry_sdk/integrations/arq.py 100.00% 14/14 covered; partial branches: 187
sentry_sdk/integrations/asyncio.py 87.50% 7/8 covered; missed: 164
sentry_sdk/integrations/boto3/_services/kinesis.py 100.00% 20/20 covered; partial branches: 21
sentry_sdk/integrations/boto3/_services/sqs.py 100.00% 20/20 covered; partial branches: 35
sentry_sdk/integrations/boto3/_services/stepfunctions.py 100.00% 38/38 covered; partial branches: 57
sentry_sdk/integrations/bottle.py 100.00% 11/11 covered; partial branches: 118
sentry_sdk/integrations/dramatiq.py 100.00% 17/17 covered; partial branches: 170
sentry_sdk/integrations/falcon.py 100.00% 15/15 covered; partial branches: 97
sentry_sdk/integrations/httpx.py 100.00% 40/40 covered; partial branches: 177
sentry_sdk/integrations/httpx2.py 100.00% 40/40 covered; partial branches: 177
sentry_sdk/integrations/litellm.py 100.00% 14/14 covered; partial branches: 124
sentry_sdk/integrations/logging.py 100.00% 29/29 covered; partial branches: 148
sentry_sdk/integrations/loguru.py 100.00% 14/14 covered; partial branches: 154
sentry_sdk/integrations/openai_agents/patches/error_tracing.py 100.00% 3/3 covered; partial branches: 58
sentry_sdk/integrations/pymongo.py 100.00% 24/24 covered; partial branches: 108
sentry_sdk/integrations/redis/utils.py 100.00% 7/7 covered; partial branches: 107
sentry_sdk/integrations/rq.py 100.00% 15/15 covered; partial branches: 124
sentry_sdk/integrations/sanic.py 100.00% 32/32 covered; partial branches: 186
sentry_sdk/integrations/threading.py 50.00% 1/2 covered; missed: 65
sentry_sdk/integrations/wsgi.py 100.00% 38/38 covered; partial branches: 429
sentry_sdk/profiler/continuous_profiler.py 50.00% 1/2 covered; missed: 84
sentry_sdk/_compat.py 100.00% 4/4 covered
sentry_sdk/_span_batcher.py 100.00% 11/11 covered
sentry_sdk/_types.py 100.00% 1/1 covered
sentry_sdk/ai/utils.py 100.00% 2/2 covered
sentry_sdk/consts.py 100.00% 76/76 covered
sentry_sdk/envelope.py 100.00% 1/1 covered
sentry_sdk/feature_flags.py 100.00% 3/3 covered
sentry_sdk/integrations/init.py 100.00% 3/3 covered
sentry_sdk/integrations/_asgi_common.py 100.00% 20/20 covered
sentry_sdk/integrations/_wsgi_common.py 100.00% 11/11 covered
sentry_sdk/integrations/ariadne.py 100.00% 9/9 covered
sentry_sdk/integrations/aws_lambda/consts.py 100.00% 5/5 covered
sentry_sdk/integrations/beam.py 100.00% 7/7 covered
sentry_sdk/integrations/boto3/_client.py 100.00% 12/12 covered
sentry_sdk/integrations/boto3/_context.py 100.00% 1/1 covered
sentry_sdk/integrations/boto3/_instrumentation.py 100.00% 28/28 covered
sentry_sdk/integrations/boto3/_services/dynamodb.py 100.00% 10/10 covered
sentry_sdk/integrations/boto3/services/lambda.py 100.00% 10/10 covered
sentry_sdk/integrations/boto3/_services/registry.py 100.00% 9/9 covered
sentry_sdk/integrations/boto3/_services/s3.py 100.00% 45/45 covered
sentry_sdk/integrations/boto3/_services/secretsmanager.py 100.00% 26/26 covered
sentry_sdk/integrations/boto3/_services/sns.py 100.00% 10/10 covered
sentry_sdk/integrations/boto3/consts.py 100.00% 2/2 covered
sentry_sdk/integrations/clickhouse_driver.py 100.00% 19/19 covered
sentry_sdk/integrations/dedupe.py 100.00% 5/5 covered
sentry_sdk/integrations/django/signals_handlers.py 100.00% 4/4 covered
sentry_sdk/integrations/django/tasks.py 100.00% 4/4 covered
sentry_sdk/integrations/executing.py 100.00% 1/1 covered
sentry_sdk/integrations/fastapi.py 100.00% 14/14 covered
sentry_sdk/integrations/gql.py 100.00% 3/3 covered
sentry_sdk/integrations/graphene.py 100.00% 12/12 covered
sentry_sdk/integrations/grpc/init.py 100.00% 2/2 covered
sentry_sdk/integrations/grpc/aio/server.py 100.00% 10/10 covered
sentry_sdk/integrations/huey.py 100.00% 16/16 covered
sentry_sdk/integrations/launchdarkly.py 100.00% 9/9 covered
sentry_sdk/integrations/openai_agents/patches/models.py 100.00% 9/9 covered
sentry_sdk/integrations/openai_agents/spans/init.py 100.00% 1/1 covered
sentry_sdk/integrations/openai_agents/spans/execute_tool.py 100.00% 8/8 covered
sentry_sdk/integrations/openai_agents/spans/invoke_agent.py 100.00% 8/8 covered
sentry_sdk/integrations/openai_agents/utils.py 100.00% 15/15 covered
sentry_sdk/integrations/openfeature.py 100.00% 5/5 covered
sentry_sdk/integrations/pydantic_ai/init.py 100.00% 46/46 covered
sentry_sdk/integrations/pydantic_ai/spans/init.py 100.00% 1/1 covered
sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py 100.00% 10/10 covered
sentry_sdk/integrations/pydantic_ai/spans/utils.py 100.00% 5/5 covered
sentry_sdk/integrations/pydantic_ai/utils.py 100.00% 10/10 covered
sentry_sdk/integrations/redis/init.py 100.00% 6/6 covered
sentry_sdk/integrations/redis/_async_common.py 100.00% 15/15 covered
sentry_sdk/integrations/redis/_sync_common.py 100.00% 9/9 covered
sentry_sdk/integrations/redis/modules/caches.py 100.00% 7/7 covered
sentry_sdk/integrations/redis/redis.py 100.00% 6/6 covered
sentry_sdk/integrations/rust_tracing.py 100.00% 12/12 covered
sentry_sdk/integrations/spark/spark_driver.py 100.00% 8/8 covered
sentry_sdk/integrations/statsig.py 100.00% 1/1 covered
sentry_sdk/integrations/stdlib.py 100.00% 32/32 covered
sentry_sdk/integrations/trytond.py 100.00% 11/11 covered
sentry_sdk/integrations/typer.py 100.00% 5/5 covered
sentry_sdk/integrations/unleash.py 100.00% 5/5 covered
sentry_sdk/transport.py 100.00% 3/3 covered
Coverage diff
@@            Coverage Diff             @@
##        master     #5005       +/-##
==========================================
- Coverage    90.29%    90.17%    -0.12%
==========================================
  Files          203       198        -5
  Tracked lines     26883     21324     -5559
  Branches     10046      7382     -2664
==========================================
- Hits         24272     19227     -5045
+ Misses        2611      2097      -514
+ Partials      1518      1238      -280

Generated by Coverage Action

@github-actions

github-actions Bot commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

⚪ None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (logging) Separate ignore lists for events/breadcrumbs and sentry logs by sl0thentr0py in #5698

Bug Fixes 🐛

Anthropic

  • Set exception info on streaming span when applicable by alexander-alderman-webb in #5683
  • Patch AsyncStream.close() and AsyncMessageStream.close() to finish spans by alexander-alderman-webb in #5675
  • Patch Stream.close() and MessageStream.close() to finish spans by alexander-alderman-webb in #5674

Documentation 📚

  • Add note on AI PRs to CONTRIBUTING.md by sentrivana in #5696

Internal Changes 🔧

  • Add -latest alias for each integration test suite by sentrivana in #5706
  • Use date-based branch names for toxgen PRs by sentrivana in #5704
  • 🤖 Update test matrix with new releases (03/19) by github-actions in #5703
  • Add client report tests for span streaming by sentrivana in #5677

Other

  • Next Python SDK major by sentrivana in #5005
  • Update CHANGELOG.md by sentrivana in #5685

🤖 This preview updates automatically when you update the PR.

Comment thread sentry_sdk/consts.py
Comment thread sentry_sdk/integrations/otlp.py
Comment thread tests/integrations/django/asgi/test_asgi.py
Comment thread sentry_sdk/integrations/otlp.py
Comment thread tests/integrations/threading/test_threading.py Outdated
Comment thread sentry_sdk/integrations/launchdarkly.py Outdated
Comment thread sentry_sdk/scope.py Outdated
Comment thread sentry_sdk/integrations/trytond.py
Comment thread sentry_sdk/integrations/chalice.py
Comment thread sentry_sdk/integrations/openai_agents/__init__.py
Comment thread sentry_sdk/integrations/pydantic_ai/__init__.py
Comment thread sentry_sdk/integrations/spark/spark_driver.py
Comment thread tests/integrations/launchdarkly/test_launchdarkly.py
Comment thread sentry_sdk/integrations/__init__.py Outdated
Comment thread sentry_sdk/integrations/openai_agents/__init__.py
Comment thread sentry_sdk/integrations/starlette.py
sentrivana added a commit that referenced this pull request Aug 6, 2026
Fixes for things that the bots
[surfaced](#5005) on the
major branch:
- some version checks were too late (after patching)
- fix TrytondWSGI integration name/`_MIN_VERSIONS` entry mismatch

Also, changed the warning of the `DidNotEnable` message from "X not
installed" to "X not installed or incompatible".
Comment thread sentry_sdk/integrations/redis/modules/queries.py
Comment thread sentry_sdk/integrations/langchain.py
Comment thread sentry_sdk/spotlight.py
Comment thread sentry_sdk/spotlight.py
Comment thread sentry_sdk/integrations/otlp.py
Comment thread sentry_sdk/integrations/aiomysql.py
Comment thread sentry_sdk/integrations/aiomysql.py Outdated
Comment thread MIGRATION_GUIDE.md Outdated
Comment thread sentry_sdk/integrations/otlp.py
Comment thread sentry_sdk/integrations/pyramid.py Outdated
Comment thread sentry_sdk/integrations/strawberry.py Outdated
Comment thread tests/integrations/aiomysql/test_aiomysql.py
Comment thread tests/integrations/aiomysql/test_aiomysql.py
Comment thread tests/integrations/aiomysql/test_aiomysql.py
Comment thread sentry_sdk/integrations/stdlib.py Outdated
Comment thread sentry_sdk/integrations/stdlib.py Outdated
Comment thread sentry_sdk/integrations/__init__.py
Comment thread sentry_sdk/integrations/threading.py
Comment thread tests/integrations/bottle/test_bottle.py
Comment thread tests/integrations/httpx/test_httpx.py Outdated
sentrivana added a commit that referenced this pull request Aug 26, 2026
Originally raised by a bot
[here](#5005 (comment)):
the `parse_version` function parses version strings as is (e.g. 3.1
becomes `(3, 1)`). We use these parsed version tuples in integrations to
compare the installed version against the minimum (defined in
`integrations/__init__.py`). The minimum versions are often three-part,
e.g. `(3, 1, 0)`.

This means that we can mistakenly consider a valid version to be below
the minimum, because in pure tuple terms, `(3, 1) < (3, 1, 0)` is true.

This can also happen in reverse (package version has three parts, while
our min version boundary has two).

In this PR, we make the internal version comparison work as expected
regardless of mismatches in the length of the version strings/tuples.
Comment thread sentry_sdk/integrations/typer.py
Comment thread sentry_sdk/_init_implementation.py
Comment thread sentry_sdk/integrations/arq.py Outdated
Comment thread sentry_sdk/integrations/asgi.py Outdated
Comment thread sentry_sdk/integrations/strawberry.py Outdated
Comment thread sentry_sdk/integrations/redis/redis.py
Comment thread sentry_sdk/integrations/stdlib.py Outdated
Comment thread MIGRATION_GUIDE.md Outdated
Comment thread MIGRATION_GUIDE.md Outdated
Comment thread sentry_sdk/consts.py
Comment thread sentry_sdk/integrations/anthropic.py Outdated
Comment thread sentry_sdk/integrations/ray.py Outdated
Comment thread MIGRATION_GUIDE.md
Comment thread sentry_sdk/integrations/pymongo.py
Comment thread sentry_sdk/integrations/redis/_async_common.py Outdated
Comment thread sentry_sdk/transport.py
@pabloDeputter
pabloDeputter added this pull request to stack #8038 October 14, 2026 20:14
@pabloDeputter
pabloDeputter removed this pull request from stack #8038 October 14, 2026 20:15
sentrivana and others added 10 commits October 15, 2026 14:00
### Description
boto3 spans now use `sentry.op = rpc` instead of `http.client`. Service
extensions can (and will in the future) provide a more specific op with
`get_span_op()`, e.g. `db` for DynamoDB.

### Why
- boto3 span represents an AWS api call, not an HTTP request; the HTTP
request is already captured as the as the `http.client` child
- JS already also defaults AWS SDK spans to `rpc`

It also lets these spans use new name and description rules in
sentry-conventions, e.g. (getsentry/sentry-conventions#714, #717), e.g.
`Lambda.Invoke billing` instead of `POST https://lambda.…`
### Description
Rename the boto3 span origin from `auto.http.boto3` to `auto.aws.boto3`,
for every boto3 span including the streamed response body child, and
removes the unused `get_span_origin()` method from `_ServiceExtension`.

### Why
1. `auto.http.boto3` describes the underlying transport/integration
used; boto3 spans are AWS API calls, and (in the future) the ops will be
changed from `http.client` => `rpc`, `db`, `queue.*`, `object.*`, so it
doesn't really fit anymore.
2. JS does the same and uses `auto.aws.aws_sdk`.

### Other option
The other option is to use `auto.rpc.boto3` as the default origin (since
`aws` isn't technically part of the categories, even though JS uses it
https://develop.sentry.dev/sdk/telemetry/traces/trace-origin/) and
override it with the span's op for different services:
- `db` => `auto.db.boto3`
- `queue.*` => `auto.queue.boto3`
- `object.* ` => `auto.object.boto3`
- streamed body child has op `http.client.stream` => `auto.http.boto3`
### Description
Move aws-lambda integraton into package; moved some constants that are
now used across modules in `aws_lambda/consts.py`.

Mainly done for ease of future development and diff-checks
### Description
- use of f-strings instead `”...”.format()`.
- move constants into `consts.py`.
- add new attributes to `SPANDATA` (will be used in the next PR).
### Description
Expand aws-lambda instrumentation with extra resource identity and
runtime metadata following OTel
(https://opentelemetry.io/docs/specs/semconv/faas/aws-lambda/).

Changes:
- add `sentry.kind=server`.
- add `cloud.account.id`, extracted from the invoked function ARN.
- `cloud.resource_id` is now normalized from the invoked function ARN;
keep the original value in `aws.lambda.invoked_arn` and replace an alias
with the resolved published version when the function is not `$LATEST`.
- `cloud.region` is now extracted from `AWS_REGION` env. var;
`faas.name` from `AWS_LAMBDA_FUNCTION_NAME`; `faas.version` from
`AWS_LAMBDA_FUNCTION_VERSION` following OTel
(https://opentelemetry.io/docs/specs/semconv/faas/aws-lambda/#resource-detector).
- refresh `sentry_sdk` on every test setup (for easier local testing so
runs don’t reuse old behavior from earlier implementation).
- add `capture_internal_exceptions()` around attribute extraction so
that a single failure does not affect the other instrumentation.


#### Issues
Resolves #7931
### Description
Adds the following attributes:
- `aws.secretsmanager.secret.arn` (OTel): from an ARN `SecretID`,
replaced by the response `ARN` (if available).
- `aws.secretsmanager.secret.name` (getsentry/sentry-conventions#716):
from response `Name` or the request `Name` or `SecretId`, else the ARN
without its random `-XXXXXX` suffix (in case of failed calls).

The actual secret values are never read.

#### Issues
Resolves #7574
## Description
Adds the following attributes:
- `aws.step_functions.state_machine.arn`, `*.activity.arn` (OTel) and
`*.execution.arn` (getsentry/sentry-conventions#672), from the request
and response.
- `aws.step_functions.state_machine.name` and `*.activity.name`
(getsentry/sentry-conventions#716), from `name` on create calls or from
the ARN without its version/alias qualifier.

Whenever `StartSyncExecution` returns a failed call (`FAILED` or
`TIMED_OUT`), `error.type` will be set to the respective value.


### Issues
Resolves #7478
### Description
Adds the following attribute:
- `aws.kinesis.stream_name` (OTel): from `StreamName`, else from the
stream in `StreamARN`, `ConsumerARN` or `ResourceARN`
(`…:stream/<name>[/consumer/…]`).

#### Issues
Resolves #7575
sentrivana and others added 5 commits October 21, 2026 13:37
Updated the changelog for the upcoming 3.0.0b1 release, highlighting notable changes, new features, and migration resources.
## Description

Adds span links as is specified in the [specs](https://develop.sentry.dev/sdk/telemetry/spans/#span-links): a span can reference other spans, e.g. in other traces, without making them its parent.

- `sentry_sdk.start_span(..., links=[...])`, `span.add_link(link)` and `span.add_links(links)`; with links being of the following format: `{"trace_id", "span_id", "sampled"?, "attributes"?}`
- span without links omits `links`
- `NoOpSpan` ignores links
- added to the migration guide as well
- [example](https://sentry-sdks.sentry.io/explore/traces/trace/8194b70609574447aa8732f24e1350a0/?mode=samples&node=span-bad54d1bc8cb9604&project=4511733153660928&source=traces&statsPeriod=24h&table=trace&timestamp=1792484175.113) in sentry-test

Related docs update can be found [here](getsentry/sentry-docs#20103).

## Why
An SQS/SNS consumer can receive a batch of records sent by several producers, each in its own trace. A span can only have one parent, so without links there's no way to connect the consumer each producer. With links the consumer span can point to each producer's trace.
Comment thread MIGRATION_GUIDE.md
Comment on lines +21 to +33
identity = aws_event.get("requestContext", {}).get("identity")
if identity is None:
return {}

user_info: "dict[str, Any]" = {}

user_arn = identity.get("userArn")
if user_arn is not None:
user_info["id"] = user_arn

ip = identity.get("sourceIp")
if ip is not None:
user_info["ip_address"] = ip

@sentry-warden sentry-warden Bot Oct 23, 2026 •

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.

_get_user_from_event crashes on non-dict requestContext/identity

Use isinstance checks for requestContext and identity before calling .get — a null or non-dict value raises AttributeError; the handler invokes this outside capture_internal_exceptions and can fail the Lambda before user code runs, and the event processor path can drop the error event.

Evidence
  • _get_user_from_event does aws_event.get("requestContext", {}).get("identity"); if the requestContext key is present with value None (or another non-dict), the default {} is skipped and .get raises AttributeError.
  • After the identity is None guard, identity.get("userArn") / identity.get("sourceIp") still assume a mapping, so a non-dict identity also raises.
  • _handler.py calls _get_user_from_event(request_data) outside capture_internal_exceptions when data_collection["user_info"] is true (the default), so the exception aborts sentry_handler before the user handler runs.
  • The same helper runs inside the request event processor; Scope.run_event_processors treats a processor exception as a dropped event.
  • The same file already guards headers with isinstance(..., dict) (e.g. _get_url), but not requestContext/identity.

Identified by Warden · code-review, find-bugs · RSZ-TZN

Comment on lines +132 to +142
if "queryStringParameters" in request_data:
qs = request_data["queryStringParameters"]
if qs:
filtered_qs = _apply_key_value_collection_filtering(
items=qs,
behaviour=data_collection["url_query_params"],
)
if filtered_qs:
additional_attributes[SPANDATA.URL_QUERY] = urlencode(
filtered_qs
)

@sentry-warden sentry-warden Bot Oct 23, 2026 •

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.

queryStringParameters assumed to be a Mapping

Check isinstance(qs, Mapping) (or wrap in capture_internal_exceptions) before filtering: a truthy non-dict value makes _apply_key_value_collection_filtering call .items() and crash the invocation.

Evidence
  • The branch only checks if qs: then passes qs to _apply_key_value_collection_filtering(items=qs, ...).
  • That helper always does items.items() with no type guard.
  • Unlike headers (explicitly coerced to {} when not a dict for EventBridge), queryStringParameters has no isinstance check.
  • This path is outside capture_internal_exceptions, so a bad value aborts sentry_handler before the user handler runs.

Identified by Warden · find-bugs, code-review · FLN-MQ8

Comment thread sentry_sdk/integrations/aws_lambda/_runtime.py
from sentry_sdk.consts import SPANDATA
from sentry_sdk.traces import StreamedSpan
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.traces import Span

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.

Closing a Cohere chat stream leaves its Span active

If a consumer closes the returned chat_stream iterator before it is exhausted, GeneratorExit bypasses the except Exception handler and span.end() is skipped. Because the span was activated when chat_stream was called, the current scope can retain that unfinished span and use it as the parent for later spans.

Evidence
  • _wrap_chat starts an active span before returning the wrapped stream iterator.
  • new_iterator calls span.end() only after normal exhaustion; its cleanup handler catches Exception, not GeneratorExit.
  • There is no finally block, so closing a suspended iterator skips span.end().
  • Span._end() restores the previous scope span; without it, the scope can retain the unfinished span.
Also found at 2 additional locations
  • sentry_sdk/integrations/cohere.py:224-246
  • sentry_sdk/integrations/cohere.py:197-260

Identified by Warden · find-bugs · AZ7-GHE

Comment thread sentry_sdk/integrations/gql.py
Comment thread sentry_sdk/integrations/gql.py
Comment thread sentry_sdk/consts.py
sample_rate: float = 1.0,
send_default_pii: "Optional[bool]" = None,
data_collection: "Optional[DataCollectionUserOptions]" = None,
data_collection: "Optional[DataCollectionUserOptions]" = {},

@sentry-warden sentry-warden Bot Oct 27, 2026 •

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.

data_collection typed Optional but None raises TypeError

Drop Optional from the annotation (or accept None in _resolve_data_collection); type checkers allow data_collection=None, but init will raise TypeError.

Evidence
  • ClientConstructor.__init__ types data_collection as Optional[DataCollectionUserOptions] with default {}.
  • DEFAULT_OPTIONS is built from these defaults via _get_default_options() / inspect.getfullargspec.
  • _resolve_data_collection() does isinstance(user_dc, dict) and raises TypeError for any non-dict, including None.
  • _get_options() always calls _resolve_data_collection(rv), so sentry_sdk.init(data_collection=None) fails at runtime despite the Optional type.

Identified by Warden · code-review, find-bugs · BW5-RFW

pabloDeputter and others added 2 commits October 27, 2026 17:16
### Description
S3 object operations now override default `rpc` op with `object.*`.
Other S3 operations, e.g. `ListBuckets`, stay on `rpc`.
…into-3.0

# Conflicts:
#	.github/workflows/test-integrations-agents.yml
#	.github/workflows/test-integrations-cloud.yml
#	scripts/populate_tox/config.py
#	scripts/populate_tox/package_dependencies.jsonl
#	scripts/populate_tox/releases.jsonl
#	scripts/populate_tox/tox.jinja
#	sentry_sdk/integrations/falcon.py
#	tests/integrations/falcon/test_falcon.py
#	tox.ini

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants