[UPSTREAM CHANGES] latest changes as of Mon Jun 08 2026 01:18:00 GMT+0000 (Coordinated Universal Time) - #232
Open
github-actions[bot] wants to merge 5554 commits into
Open
[UPSTREAM CHANGES] latest changes as of
Mon Jun 08 2026 01:18:00 GMT+0000 (Coordinated Universal Time)#232github-actions[bot] wants to merge 5554 commits into
github-actions[bot] wants to merge 5554 commits into
Conversation
chore(deps): update dependency locust to v2.43.4 See merge request glitchtip/glitchtip-backend!2269
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: use keyword arg for AuthenticationError to avoid string status_code See merge request glitchtip/glitchtip-backend!2266
Update dependency boto3 to v1.42.82 See merge request glitchtip/glitchtip-backend!2270
Update dependency django-allauth to v65.15.1 See merge request glitchtip/glitchtip-backend!2271
Update dependency ruff to v0.15.9 See merge request glitchtip/glitchtip-backend!2272
- Add `profile_chunk` to IgnoredItemType so sentry-javascript v9+ continuous profiling envelopes are silently skipped instead of logging 10 000+ validation errors (INTERNAL-4I) - Guard against None stacktrace in StacktraceProcessor.resolve_stacktrace when an exception entry has no stacktrace key (INTERNAL-3, 161 events) - Strip NUL (0x00) bytes from SpanStaging text fields (transaction_name, op, description) before bulk insert to prevent DataError (INTERNAL-76) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: resolve three production ingest errors See merge request glitchtip/glitchtip-backend!2274
Update dependency boto3 to v1.42.83 See merge request glitchtip/glitchtip-backend!2275
sentry-dart <= 9.6.0 serializes log item timestamps as ISO-8601 strings (e.g. "2026-04-03T02:57:11.646571Z") rather than the Unix float seconds required by the OTel logs spec. This was fixed upstream in later versions, but shipped 9.6.0 clients continue to send ISO strings, producing hundreds of pydantic float_parsing validation errors per day (INTERNAL-6R and ~10 sibling issues in production). Coerce ISO-8601 strings to Unix float in LogItemSchema's before-validator so these payloads ingest cleanly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Flutter Android events send native frames (with instruction_addr) but were incorrectly routed to the proguard resolver because is_android_event() returned True. This caused the DIF query to filter for proguard mappings only, skipping the uploaded ELF debug symbols entirely. The fix detects native frames by checking for instruction_addr rather than hard-coding SDK names, so any platform sending native frames on Android (Flutter, React Native with Hermes, etc.) is handled correctly. Additional fixes: - Estimate image base when debug_meta/image_addr is absent, by probing the sym_cache with candidate offsets - Fall back to first archive object when device arch is unknown - Skip 32-bit DIFs when instruction addresses are clearly 64-bit - Prefer DIFs that resolve frames with real filenames when scores tie - Remove debug_meta requirement from _has_difs fallback gate Closes https://gitlab.com/glitchtip/glitchtip-backend/-/work_items/472 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use next(sym_cache.lookup(), None) instead of list() in hot loop - Use parse_addr() instead of int(addr, 16) to handle malformed data - Use explicit None check for image_addr instead of falsy-or pattern, so image_addr=0x0 is not conflated with absent Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update dependency boto3 to v1.42.84 See merge request glitchtip/glitchtip-backend!2281
…ning corrupt files The /events/latest/ cold storage fallback was scanning ALL parquet files for an org (start_dt=datetime.min), which could mean 60+ files for default retention or thousands with custom retention. Now uses issue.last_seen ± 1 day to narrow to ~2 files. Also stops cycling DuckDB connections on corrupt files (the connection is fine, only the file is bad) and auto-deletes corrupt parquet files so they don't cause repeated failures on future requests. Triggered by: OutOfMemoryException in production where 6 corrupt files caused repeated connection churn before the actual query OOM'd. AI Contribution: Claude Code assisted with implementation and testing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update dependency sentry-sdk to v2.57.0 See merge request glitchtip/glitchtip-backend!2265
Update dependency mcp to v1.27.0 See merge request glitchtip/glitchtip-backend!2276
Update dependency ipython to v9.12.0 See merge request glitchtip/glitchtip-backend!2257
Update dependency django-debug-toolbar to v6.3.0 See merge request glitchtip/glitchtip-backend!2273
Fix symbolication of obfuscated Flutter Android stack traces Closes #472 See merge request glitchtip/glitchtip-backend!2280
Per spec: license_key is a server-side credential and never flows to the frontend. Future operator actions (support link, invoice link) will be purpose-built endpoints that embed the key server-side. - Drop license_key from InstanceLicenseOut schema and handler - Replace test_response_omits_license_key + test_per_field_merge_env_key_with_db_email with focused tests covering env-source, DB-source, and BILLING_ENABLED short-circuit
Admin-set license now immediately enables paid features (e.g., Manage Billing button) without requiring a restart, fulfilling the "admin or env" promise that the env-only wiring previously broke. - get_settings() reads SupportLicense.license_key from DB instead of settings.I_PAID_FOR_GLITCHTIP env - BILLING_ENABLED short-circuits to True (hosted GlitchTip = always paid) - Trim env-related InstanceLicenseTestCase decorators (env vars dropped in !2361) - Add test_i_paid_for_glitchtip_reflects_support_license to verify wiring
Comment said /api/0/settings/, actual route is /api/settings/ (NinjaAPI
mounted at api/ with @api.get("settings/") — no 0/ prefix). David's
drive-by from !2364 review.
…d on !2361) Follow-up to !2361's rename: get_instance_license now calls the renamed async method without the a-prefix.
…1/foundation-and-sub-swap' feat(api): authenticated instance-license endpoint; remove license_key from public settings See merge request glitchtip/glitchtip-backend!2364
feat(stripe): instance-wide SupportLicense singleton + env-wins resolver + admin See merge request glitchtip/glitchtip-backend!2361
Bumps symbolic from 12.18.x to 13.1.1, updating both pyproject.toml and uv.lock together so `uv sync --frozen` (CI and the Docker build) stays consistent. The major version bump originates from symbolic's internal Rust dependency updates (gimli, goblin, scroll) and added Windows ARM64 support; there are no breaking changes to the Python API GlitchTip uses (SourceMapCache, normalize_debug_id, Archive, parse_addr, ProguardMapper, SymCache). Full test suite passes locally (1071 tests). Supersedes the Renovate MR, which only bumped pyproject.toml (leaving uv.lock inconsistent) and had fallen behind master. AI-assisted change (Claude Code); human review required before merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lockfile-only bump from 2.4.0 to 2.5.0. The constraint in pyproject.toml (~=2.2) already permits it. 2.5.0 newly declares django as an explicit dependency (previously only prometheus-client), which is satisfied by the existing top-level Django dependency. Replaces the stale Renovate MR !2234, whose branch had become unmergeable against master (uv.lock conflict). Note the branch-push pipeline on that MR passed at the same SHA; only the merge-result pipeline failed, due to the conflict — not a test regression. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chore(deps): update symbolic to 13.1.1 See merge request glitchtip/glitchtip-backend!2369
chore(deps): update django-prometheus to 2.5.0 See merge request glitchtip/glitchtip-backend!2370
update_uptime_statistics wrapped its INSERT ... ON CONFLICT in
async_atomic(). That was safe when django-async-backend was always
active, because async_atomic opened a transaction on a per-task async
connection. Since async-backend became opt-in (USE_ASYNC_BACKEND,
default off), async_atomic is a sync_to_async shim over Django's
thread-local connection, which the async worker shares across
concurrently running tasks.
Holding that transaction open across the await inside the block lets a
sibling task close or reset the shared connection mid-block. The next
statement then fails with "Cannot open a new connection in an atomic
block", which poisons the connection and surfaces downstream as
TransactionManagementError ("can't execute queries until the end of the
'atomic' block").
A single INSERT ... ON CONFLICT is atomic on its own and needs no
surrounding transaction, so drop the wrapper. The existing IntegrityError
fallback for a missing partition is unchanged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
StripeProduct.sync_from_stripe() deletes every product not present in Stripe's latest product list. StripePrice.product is CASCADE, but StripeSubscription.price is RESTRICT, so when a product archived in Stripe still has a price referenced by a live (often grandfathered) subscription, the cascade delete raises RestrictedError and aborts the entire daily sync_stripe_models maintenance step. Exclude products whose prices are still referenced by any subscription from the deletion. Retaining them is harmless: they simply no longer appear in Stripe's product listing, and they remain valid targets for the subscriptions that point at them. Genuinely stale products with no referencing subscription are still pruned. Adds two regression tests: one asserting a referenced-but-archived product survives the sync (reproduces the RestrictedError without the fix), and one asserting unreferenced archived products are still deleted so the retention guard doesn't disable ordinary cleanup. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ter' fix(stripe): don't delete products still referenced by a subscription See merge request glitchtip/glitchtip-backend!2373
fix(uptime): drop async_atomic around hourly-stats upsert See merge request glitchtip/glitchtip-backend!2371
The CI `lint` job runs `vulture` in addition to `ruff`; the guidance only mentioned ruff, so dead-code findings (e.g. an unused signal-handler param) surfaced only in CI. Document the vulture command so it's run locally too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a first-class "email disabled" mode so self-hosted installs with no MTA run cleanly instead of crashing on the default SMTP to localhost:25. - settings.EMAIL_ENABLED autodetects a configured transport; the bare smtp -> localhost:25 default with no admin config is treated as disabled. EMAIL_ENABLED env var forces either mode. A configured-but- broken transport still fails loudly (disabled mode is only entered when email is genuinely unconfigured). - Two deterministic "don't send" chokepoints: GlitchTipEmail._send_email and CustomDefaultAccountAdapter.send_mail return early when disabled. No routing to the console backend / swallowed send errors. - Account email verification disabled (ACCOUNT_EMAIL_VERIFICATION="none") so an account email stays unverified/untrusted; the invite verification gate is bypassed so it can't block all invites. - Invite acceptance link surfaced on the member-create response so the frontend can offer a copy-link invite flow. - /api/settings/ enabled_features lists "email" when enabled so the frontend can hide email-dependent UI (password reset, resend confirmation). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces the Mode line (web-only vs all-in-one, soon non-configurable) with the email transport, so the email-disabled state is visible on a fresh boot instead of being silent: Email: disabled (no transport configured) Email: SMTP # or Anymail (mailgun), console, file States what is configured -- never connectivity, never secrets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 0.x -> 6.x jump is a versioning-scheme change only: the package now tracks Django's version line. The actual delta is bug fixes. Pin to ~=6.0 to match the django~=6.0 ecosystem constraint. async-backend remains opt-in behind USE_ASYNC_BACKEND (default off), so this is inert in the default (sync-shim) path; it ships the fixed version for when the flag is enabled. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deletes The DELETE endpoints for projects, project keys, and teams gate on an organization admin role, but the role filter joined a different organization-membership row than the one identifying the caller. Because membership (`organization__users=user_id`) and the role check (`organization__organization_users__role__gte=ADMIN`) traversed two independent relations, they matched two unrelated rows: the query only verified that *some* admin existed in the organization (effectively always true, since every org has an owner), never that the requester was an admin. The scope decorator only enforces scopes for token auth, so a non-admin member authenticated via a browser session could delete projects, DSN keys, and teams in their own organization. Fix by placing the user and role conditions on the same `organization_users` relation within a single filter, so both must match the same row — the pattern already used for the Stripe owner checks and team-membership modification. Scope is intra-organization only: the actor must already be an authenticated member of the org, and project/org deletes are soft deletes. Other endpoints sharing this pattern (alert deletion, team/project association, and the create endpoints) are intentionally left for a separate discussion on what organization roles should enforce, since their correct behavior is a policy question rather than a clear bug. Reported by @Gumbraise. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix: pin admin role check to the requesting user on destructive deletes See merge request glitchtip/glitchtip-backend!2377
Summarize changes since v6.1.6, grouped by Security/Feat/Perf/Fix/Deps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… cascade With USE_ASYNC_BACKEND off (the default), glitchtip.async_compat is a sync_to_async shim over Django's thread-local connection, which the async worker shares across concurrently running tasks. _create_issue_and_hash held async_atomic() open across awaited cursor calls, so a sibling task could close or poison the shared connection mid-transaction — cascading as "Cannot open a new connection in an atomic block" / TransactionManagementError across unrelated ingest, uptime, span-promotion, and alert tasks. Run the project-counter upsert plus the Issue/IssueHash writes inside a single sync_to_async hop using vanilla transaction.atomic() and a raw cursor (the pre-shim structure), so the transaction never spans an await. Tests: retire the AsyncQueryCounter shim-cursor counter and return the ingest query-count assertions to Django's standard assertNumQueries / CaptureQueriesContext, which observe all queries on the sync connection regardless of sync/async cursor routing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(ingest): run issue creation in a single transaction to stop async connection cascade See merge request glitchtip/glitchtip-backend!2378
Some SDKs (e.g. sentry-go on client_report envelopes, which carry no associated event) send an empty string for the optional envelope-header `event_id` field rather than omitting the key. The field is typed `uuid.UUID | None`, but the default only applies when the key is absent — an empty string still hits UUID parsing and raises ValidationError, so the entire envelope is rejected with a 400 and the telemetry is dropped. Per the envelope spec `event_id` is optional. Coerce a blank value to None in a before-validator so these envelopes are accepted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(email): support running with email disabled when unconfigured See merge request glitchtip/glitchtip-backend!2376
fix(ingest): accept empty event_id in envelope header See merge request glitchtip/glitchtip-backend!2379
The validate_build_arm64 job requires the saas-linux-medium-arm64 runner tag, which only the canonical glitchtip/glitchtip-backend project has. On a fork (e.g. an outside contributor's MR), the job resolves to no_matching_runner and reports as failed without running anything, making a green pipeline look red. Gate the job to the canonical project so forks skip it entirely; the amd64 validate job still runs there and carries the build smoke test. Uses !reference to inherit the base rules rather than duplicating them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ci: skip arm64 build validation on forks See merge request glitchtip/glitchtip-backend!2382
… into upstream-changes-2026-06-08
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.
This PR is auto-generated by
actions/github-script.