Skip to content

Considerably raise DEFAULT_MAX_VALUE_LENGTH #4632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
from typing import TYPE_CHECKING

# up top to prevent circular import due to integration import
DEFAULT_MAX_VALUE_LENGTH = 1024
# This is more or less an arbitrary large-ish value for now, so that we allow
# pretty long strings (like LLM prompts), but still have *some* upper limit
# until we verify that removing the trimming completely is safe.
DEFAULT_MAX_VALUE_LENGTH = 100_000
Copy link
Member

Choose a reason for hiding this comment

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

Why not use sys.maxsize here? Then, we definitely should never need to bump this limit again.

Copy link
Member

Choose a reason for hiding this comment

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

In any case, let's add a code comment to document how we picked the value we end up going with

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Talked about this offline -- and added a comment


DEFAULT_MAX_STACK_FRAMES = 100
DEFAULT_ADD_FULL_STACK = False
Expand Down
41 changes: 30 additions & 11 deletions tests/integrations/bottle/test_bottle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from io import BytesIO
from bottle import Bottle, debug as set_debug, abort, redirect, HTTPResponse
from sentry_sdk import capture_message
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
from sentry_sdk.integrations.bottle import BottleIntegration
from sentry_sdk.serializer import MAX_DATABAG_BREADTH

Expand Down Expand Up @@ -121,9 +122,9 @@ def index():


def test_large_json_request(sentry_init, capture_events, app, get_client):
sentry_init(integrations=[BottleIntegration()])
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")

data = {"foo": {"bar": "a" * 2000}}
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}

@app.route("/", method="POST")
def index():
Expand All @@ -144,9 +145,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH


@pytest.mark.parametrize("data", [{}, []], ids=["empty-dict", "empty-list"])
Expand Down Expand Up @@ -174,9 +180,9 @@ def index():


def test_medium_formdata_request(sentry_init, capture_events, app, get_client):
sentry_init(integrations=[BottleIntegration()])
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")

data = {"foo": "a" * 2000}
data = {"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}

@app.route("/", method="POST")
def index():
Expand All @@ -194,9 +200,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]) == 1024
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH


@pytest.mark.parametrize("input_char", ["a", b"a"])
Expand Down Expand Up @@ -233,7 +244,10 @@ def index():
def test_files_and_form(sentry_init, capture_events, app, get_client):
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")

data = {"foo": "a" * 2000, "file": (BytesIO(b"hello"), "hello.txt")}
data = {
"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10),
"file": (BytesIO(b"hello"), "hello.txt"),
}

@app.route("/", method="POST")
def index():
Expand All @@ -253,9 +267,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]) == 1024
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH

assert event["_meta"]["request"]["data"]["file"] == {
"": {
Expand Down
14 changes: 10 additions & 4 deletions tests/integrations/falcon/test_falcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import falcon
import falcon.testing
import sentry_sdk
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
from sentry_sdk.integrations.falcon import FalconIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.utils import parse_version
Expand Down Expand Up @@ -207,9 +208,9 @@ def on_get(self, req, resp):


def test_falcon_large_json_request(sentry_init, capture_events):
sentry_init(integrations=[FalconIntegration()])
sentry_init(integrations=[FalconIntegration()], max_request_body_size="always")

data = {"foo": {"bar": "a" * 2000}}
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}

class Resource:
def on_post(self, req, resp):
Expand All @@ -228,9 +229,14 @@ def on_post(self, req, resp):

(event,) = events
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH


@pytest.mark.parametrize("data", [{}, []], ids=["empty-dict", "empty-list"])
Expand Down
45 changes: 34 additions & 11 deletions tests/integrations/flask/test_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
capture_message,
capture_exception,
)
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.serializer import MAX_DATABAG_BREADTH

Expand Down Expand Up @@ -248,9 +249,11 @@ def login():


def test_flask_large_json_request(sentry_init, capture_events, app):
sentry_init(integrations=[flask_sentry.FlaskIntegration()])
sentry_init(
integrations=[flask_sentry.FlaskIntegration()], max_request_body_size="always"
)

data = {"foo": {"bar": "a" * 2000}}
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}

@app.route("/", methods=["POST"])
def index():
Expand All @@ -268,9 +271,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH


def test_flask_session_tracking(sentry_init, capture_envelopes, app):
Expand Down Expand Up @@ -336,9 +344,11 @@ def index():


def test_flask_medium_formdata_request(sentry_init, capture_events, app):
sentry_init(integrations=[flask_sentry.FlaskIntegration()])
sentry_init(
integrations=[flask_sentry.FlaskIntegration()], max_request_body_size="always"
)

data = {"foo": "a" * 2000}
data = {"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}

@app.route("/", methods=["POST"])
def index():
Expand All @@ -360,9 +370,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]) == 1024
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH


def test_flask_formdata_request_appear_transaction_body(
Expand Down Expand Up @@ -441,7 +456,10 @@ def test_flask_files_and_form(sentry_init, capture_events, app):
integrations=[flask_sentry.FlaskIntegration()], max_request_body_size="always"
)

data = {"foo": "a" * 2000, "file": (BytesIO(b"hello"), "hello.txt")}
data = {
"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10),
"file": (BytesIO(b"hello"), "hello.txt"),
}

@app.route("/", methods=["POST"])
def index():
Expand All @@ -463,9 +481,14 @@ def index():

(event,) = events
assert event["_meta"]["request"]["data"]["foo"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]) == 1024
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH

assert event["_meta"]["request"]["data"]["file"] == {"": {"rem": [["!raw", "x"]]}}
assert not event["request"]["data"]["file"]
Expand Down
28 changes: 21 additions & 7 deletions tests/integrations/pyramid/test_pyramid.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from werkzeug.test import Client

from sentry_sdk import capture_message, add_breadcrumb
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
from sentry_sdk.integrations.pyramid import PyramidIntegration
from sentry_sdk.serializer import MAX_DATABAG_BREADTH
from tests.conftest import unpack_werkzeug_response
Expand Down Expand Up @@ -156,9 +157,9 @@ def test_transaction_style(


def test_large_json_request(sentry_init, capture_events, route, get_client):
sentry_init(integrations=[PyramidIntegration()])
sentry_init(integrations=[PyramidIntegration()], max_request_body_size="always")

data = {"foo": {"bar": "a" * 2000}}
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}

@route("/")
def index(request):
Expand All @@ -175,9 +176,14 @@ def index(request):

(event,) = events
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH


@pytest.mark.parametrize("data", [{}, []], ids=["empty-dict", "empty-list"])
Expand Down Expand Up @@ -230,7 +236,10 @@ def index(request):
def test_files_and_form(sentry_init, capture_events, route, get_client):
sentry_init(integrations=[PyramidIntegration()], max_request_body_size="always")

data = {"foo": "a" * 2000, "file": (BytesIO(b"hello"), "hello.txt")}
data = {
"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10),
"file": (BytesIO(b"hello"), "hello.txt"),
}

@route("/")
def index(request):
Expand All @@ -244,9 +253,14 @@ def index(request):

(event,) = events
assert event["_meta"]["request"]["data"]["foo"] == {
"": {"len": 2000, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}
assert len(event["request"]["data"]["foo"]) == 1024
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH

assert event["_meta"]["request"]["data"]["file"] == {"": {"rem": [["!raw", "x"]]}}
assert not event["request"]["data"]["file"]
Expand Down
7 changes: 6 additions & 1 deletion tests/integrations/sqlalchemy/test_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,12 @@ def processor(event, hint):

# The _meta for other truncated fields should be there as well.
assert event["_meta"]["message"] == {
"": {"len": 1034, "rem": [["!limit", "x", 1021, 1024]]}
"": {
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
"rem": [
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
],
}
}


Expand Down
11 changes: 7 additions & 4 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,14 +773,14 @@ def test_databag_string_stripping(sentry_init, capture_events, benchmark):
def inner():
del events[:]
try:
a = "A" * 1000000 # noqa
a = "A" * DEFAULT_MAX_VALUE_LENGTH * 10 # noqa
1 / 0
except Exception:
capture_exception()

(event,) = events

assert len(json.dumps(event)) < 10000
assert len(json.dumps(event)) < DEFAULT_MAX_VALUE_LENGTH * 10
Copy link

Choose a reason for hiding this comment

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

Bug: String Truncation Test Assertion Too Weak

The assertion in test_databag_string_stripping is too weak, defeating the test's purpose. This test is designed to verify that large strings are truncated to keep serialized event sizes manageable. However, the current assertion len(json.dumps(event)) < DEFAULT_MAX_VALUE_LENGTH * 10 allows the serialized event to be as large as the input string (1,000,000 bytes, given DEFAULT_MAX_VALUE_LENGTH = 100_000). This fails to ensure that truncation is actually occurring and keeping the event size manageable. The assertion should be tightened to effectively test string stripping, similar to the original < 10000 bound.

Locations (1)
Fix in Cursor Fix in Web



def test_databag_breadth_stripping(sentry_init, capture_events, benchmark):
Expand Down Expand Up @@ -1073,7 +1073,10 @@ def test_multiple_positional_args(sentry_init):
"sdk_options, expected_data_length",
[
({}, DEFAULT_MAX_VALUE_LENGTH),
({"max_value_length": 1800}, 1800),
(
{"max_value_length": DEFAULT_MAX_VALUE_LENGTH + 1000},
DEFAULT_MAX_VALUE_LENGTH + 1000,
),
],
)
def test_max_value_length_option(
Expand All @@ -1082,7 +1085,7 @@ def test_max_value_length_option(
sentry_init(sdk_options)
events = capture_events()

capture_message("a" * 2000)
capture_message("a" * (DEFAULT_MAX_VALUE_LENGTH + 2000))

assert len(events[0]["message"]) == expected_data_length

Expand Down
5 changes: 3 additions & 2 deletions tests/test_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest

from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
from sentry_sdk.serializer import MAX_DATABAG_BREADTH, MAX_DATABAG_DEPTH, serialize

try:
Expand Down Expand Up @@ -166,11 +167,11 @@ def test_no_trimming_if_max_request_body_size_is_always(body_normalizer):


def test_max_value_length_default(body_normalizer):
data = {"key": "a" * 2000}
data = {"key": "a" * (DEFAULT_MAX_VALUE_LENGTH * 10)}

result = body_normalizer(data)

assert len(result["key"]) == 1024 # fallback max length
assert len(result["key"]) == DEFAULT_MAX_VALUE_LENGTH # fallback max length


def test_max_value_length(body_normalizer):
Expand Down
Loading