Release 0.36.2 - #72
Merged
Merged
Conversation
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Production learn-ai pods show continuous "Unclosed client session" asyncio warnings and per-pod memory climbing from ~558MB to 900MB+ before replacement, alongside readiness-probe failures and APISIX p95 latency spiking to 7.5-24s. litellm's aiohttp transport (LiteLLMAiohttpTransport._get_valid_client_session in litellm/llms/custom_httpx/aiohttp_transport.py, litellm==1.89.3) caches one ClientSession per event loop and, when it detects the cached session belongs to a different/closed loop than the current one (routine across Channels' per-consumer async contexts), schedules the old session's close() as a fire-and-forget task or, if that can't be scheduled, abandons it for GC per the library's own code comment. That GC fallback is what produces the unclosed-session warnings and leaks the underlying sockets. Set litellm.disable_aiohttp_transport = True at app startup so async LLM calls fall back to httpx, which this app already pools and closes correctly via ai_chatbots.utils.HTTPClientManager. litellm's own comment claims aiohttp gives higher throughput than httpx, but that tradeoff isn't worth the active production leak. Claude-Session: https://claude.ai/code/session_017H4oTvJX9jqEixKmsTLWmp Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…TAIL rows (#62) * fix(sentry): cap request bodies at 1KB and scrub Postgres DETAIL rows Two ways learner data reaches Sentry, neither gated by send_default_pii. Request bodies. The SDK sets request.data unconditionally at sentry_sdk/integrations/_wsgi_common.py:123; max_request_body_size, checked at :61, is the only control, and left unset it defaults to "medium" -- 10,000-byte bodies. Nobody chose that. Measured over the last 30 days, the write endpoints that actually raise are the sensitive ones: SCIM user PATCH, /api/v1/enrollments/, /api/checkout/result/, /api/checkout/redeem_discount/, /api/profile/details/, and CMS page edits. Set to "small" explicitly, so the choice is findable at the call site instead of in a dependency's defaults. Postgres DETAIL lines. A constraint violation carries a DETAIL line that echoes the whole offending row, and psycopg puts it in str(exc) -- so it ships inside the exception value, which no SDK privacy option covers. Measured on mitxonline MITXONLINE-6PK: a SCIM PATCH IntegrityError reproducing a learner email address three times per event, 46,764 occurrences since 2026-05-27. before_send now truncates at the DETAIL marker across exception values, logentry, and the legacy top-level message, keeping the primary error that names the failure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVJKTGk9KHUTN2xfU59ujX * fix(sentry): scrub DETAIL rows from the whole event, not three named fields Copilot review, verified against sentry-sdk 2.55.0 source. The first pass enumerated three paths -- exception values, logentry.message/.formatted, and the legacy top-level message -- and missed every other field that can carry the same string: breadcrumbs[].message LoggingIntegration records each log record as a breadcrumb (integrations/logging.py:311). This is exactly MITXONLINE-6PK's shape: mechanism=logging, logger=django_scim.views. logentry.params record.args verbatim (:274), so logger.error("...: %s", exc) carries it. frames[].vars include_local_variables defaults to True (consts.py:1028, utils.py:616), so a catch block holding the exception in a local carries it. Confirmed the old implementation leaked on all three shapes before changing it; the new tests fail against it and pass against the walk. Replaced with a recursive walk of the event instead of a longer path list -- it covers these without enumerating them and does not go stale when the SDK grows another such field. The walk only rewrites str leaves and preserves everything else, with a test pinning that. Copilot also suggested normalizing exception-valued params. Not needed: client._prepare_event serializes the event before calling before_send (client.py:650 vs :658), so every leaf is already a JSON primitive by then and there are no live exception objects left to coerce. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVJKTGk9KHUTN2xfU59ujX * fix(sentry): scrub repr'd DETAIL lines and narrow the body-size comment The SDK repr()s frame locals and non-string logging params while serializing, so there the DETAIL line arrives with a literal backslash-n and the "\nDETAIL:" marker missed it. Match both forms, and test through the real SDK so the hand-built events can't pass while the real path leaks. The max_request_body_size comment described mitxonline payloads. Here it only reaches the regular Django views, not the Channels chatbot endpoints, and under ASGI a request with no Content-Length bypasses the bound. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MYc2F3cFvSCfVzqeRMshGy --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Anastasia Beglova
Matt Bertrand
Tobias Macey
renovate[bot]