Skip to content

[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
masterfrom
upstream-changes-2026-06-08
Open

[UPSTREAM CHANGES] latest changes as of Mon Jun 08 2026 01:18:00 GMT+0000 (Coordinated Universal Time)#232
github-actions[bot] wants to merge 5554 commits into
masterfrom
upstream-changes-2026-06-08

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

This PR is auto-generated by
actions/github-script.

bufke and others added 30 commits April 2, 2026 07:04
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
LUARM and others added 30 commits May 29, 2026 16:52
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants