Skip to content

feat!: add per-event capture options and one property precedence - #882

Merged
turnipdabeets merged 26 commits into
feat/v4-capture-v1from
feat/v4-capture-options
Oct 28, 2026
Merged

turnipdabeets merged 26 commits into
feat/v4-capture-v1from
feat/v4-capture-options

Conversation

@turnipdabeets

@turnipdabeets turnipdabeets commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #881 (capture v1 transport), which is stacked on #871. #884 (captureAi) follows.

💡 Motivation and Context

Second capture v1 PR for posthog-android 4.0. #881 moved the wire to /i/v1/analytics/events and hoists the legacy $ option properties into options when a request is built. This PR adds the public side of options and aligns event building with the client precedence the SDK team agreed on for 4.0 (PostHog/sdk-specs#143, posthog-ios 4.0 in PostHog/posthog-ios#938).

Per-event options (new public API)

  • options: Map<String, Any?>? = null as the last parameter of capture, screen, identify, setPersonProperties, alias, group and captureException on PostHogInterface, PostHog and the PostHog companion. The map is copied into PostHogEvent.options before beforeSend, which can read and change it. For identify the options apply to the $identify or $set event it sends; for group to $groupidentify; for alias to $create_alias.
  • Known keys: process_person_profile, cookieless_mode, disable_skew_correction and product_tour_id. Any other key is sent as-is; values are never coerced (the server parses them leniently).
  • Precedence, lowest first: legacy $ property (hoisted by feat!: send events through capture v1 and add captureAi #881 at send time), SDK default, caller option, beforeSend. An option set to null counts as unset.
  • The 3-arg identify moved from PostHogCoreInterface to PostHogStatelessInterface; PostHogInterface has the 4-arg one. Nothing outside this repo implements PostHogCoreInterface, and Kotlin callers of PostHog.identify(...) keep compiling.

Person processing

  • The SDK sets the process_person_profile: false option only when person processing is off (personProfiles = NEVER, or IDENTIFIED_ONLY before identify). It sends nothing otherwise, like the server v1 SDKs. It no longer writes a $process_person_profile property on every event. A caller option, a caller or registered $process_person_profile property, or beforeSend wins.
  • A $set/$identify sent with process_person_profile: false neither stores nor matches the person-properties dedup hash, so a later processed call with the same properties goes out.

One property precedence (sdk-specs#143)

  • Properties the SDK sets itself (context, SDK info, feature flags, $screen_name, session id, $is_identified, replay debug values) → registered super properties → the properties passed to the call (userProperties, userPropertiesSetOnce and groups are per-call values) → beforeSend. No SDK-owned keys: in 3.x the SDK's values beat super properties, and $is_identified, $process_person_profile and the replay debug values also beat caller properties.
  • A blank caller $screen_name, $session_id or distinct_id still replaces the SDK's value, as in 3.x (explicit unset).

Smaller changes

  • An empty or whitespace-only distinctId argument to capture uses the current distinct ID, like null, instead of dropping the event.
  • An event beforeSend returns keeps the uuid of the capture it came from, so a hook that returns a cached earlier event can't repeat a uuid (capture v1 keeps only the first copy of a repeated uuid).
  • The minimal $feature_flag_called event also keeps $cookieless_mode, $ignore_sent_at and $product_tour_id, so they survive until they are converted to options.
  • Compliance adapter forwards options on /capture and advertises event_options.

Breaking changes

Change Who notices
New trailing options parameter on seven PostHogInterface methods Java callers (pass null) and anything implementing PostHogInterface
PostHogCoreInterface.identify moved to PostHogStatelessInterface / PostHogInterface Code that holds a PostHogCoreInterface reference and calls identify
Super and event properties now override SDK-set properties, including $is_identified, $process_person_profile and replay debug values Apps that register or pass those keys and expected the SDK's value
$process_person_profile is sent only when person processing is off Filters on $process_person_profile = true
beforeSend can't change an event's uuid on the client path Hooks that set uuids
Blank distinctId argument no longer drops the event Apps relying on that drop

Differences from the server v1 SDKs

  • No global or context options (same as posthog-ios 4.0). A registered legacy $ key becomes its option at send time.
  • A caller or registered legacy $process_person_profile suppresses the SDK's personless option instead of losing to it, so the hoist can make the caller's value win (locked client order: SDK-set, super, event, beforeSend).
  • Typed $set/$set_once/$groups call values beat a registered property of the same key (per-call values win); posthog-ios keeps the registered one.

💚 How did you test it?

  • ./gradlew apiCheck spotlessCheck :posthog:test :posthog-android:testReleaseUnitTest :posthog-server:test pass (core 1110, Android 765, server 609); the compliance adapter compiles.
  • New PostHogCaptureOptionsTest covers options reaching PostHogEvent.options for every method, the map copy, beforeSend edits, the personless option under each personProfiles mode, caller/registered overrides, precedence (registered beats SDK, caller beats registered, beforeSend beats caller), typed $set/$groups, the blank-distinctId fallback, the dedup hash with a personless $set, the allowlist and uuid stability. PostHogPersonProfilesTest/PostHogTest/PostHogBootstrapTest expectations were updated to the new semantics.
  • The Android event-shape snapshot was re-recorded ($process_person_profile gone; key order).
  • Flutter and React Native Android bridges keep compiling (named/positional Kotlin calls).
  • Compliance harness 1.20.0 in CI: capture_v1 suite 115/118. All event-options scenarios pass now, including unset_options_omitted. The 3 failures: non_utc_event_timestamp_is_converted_to_utc (adapter never forwarded timestamp; fixed in feat!: add captureAi on the capture v1 AI endpoint #884), geoip_disable_injected_into_properties (no SDK surface) and historical_migration_set_in_body (no historical-migration mode).

📝 Checklist

  • All commits are signed
  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file (bullets added to .changeset/android-v4-major.md)

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Built with Claude Code (Claude Fable 5.1). One subagent implemented the options API and precedence against sdk-specs#143 and the posthog-ios 4.0 branch, in parallel with #881; a review and triage pass fed fixes back. Maintainer decisions: keep the uuid pin client-only (server hooks may still set uuids), keep Android's blank-caller-value semantics, move identify off PostHogCoreInterface rather than carry two overloads.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DRbQPidntd4hVufNpMT19L

@posthog posthog Bot left a comment

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.

PostHog Review · Standard · reviewed b0edae2: 2 Should fix.

This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.

See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.

Comment thread posthog/src/main/java/com/posthog/PostHog.kt
Comment thread posthog/src/main/java/com/posthog/PostHog.kt
@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

posthog-android Compliance Report

Date: 2026-10-27T22:52:04.860887+00:00
Duration: 209943ms

⚠️ Some Tests Failed

114/118 tests passed, 4 failed


Capture_V1 Tests

⚠️ 97/101 tests passed, 4 failed

View Details
Test Status Duration
Endpoint And Method.Targets V1 Endpoint ✅ 378ms
Endpoint And Method.Does Not Use Legacy Endpoints ✅ 36ms
Required Headers.Has Authorization Bearer Header ✅ 25ms
Required Headers.Has Content Type Json ✅ 25ms
Required Headers.Has Posthog Sdk Info Format ✅ 23ms
Required Headers.Has Posthog Attempt Header ✅ 24ms
Required Headers.Has Posthog Request Id ✅ 18ms
Required Headers.Has Posthog Request Timestamp ✅ 23ms
Required Headers.Has User Agent ✅ 20ms
Body Format.Body Has Created At And Batch ✅ 23ms
Body Format.No Api Key In Body ✅ 20ms
Body Format.No Sent At In Body ✅ 19ms
Event Format.Event Has Required Root Fields ✅ 19ms
Event Format.Event Uuid Is Valid ✅ 19ms
Event Format.Event Timestamp Is Rfc3339 ✅ 17ms
Event Format.Non Utc Event Timestamp Is Converted To Utc ❌ 20ms
Event Format.Distinct Id Is String ✅ 16ms
Event Format.Distinct Id At Root Not Properties ✅ 20ms
Event Format.Custom Properties Preserved ✅ 20ms
Event Format.Set Properties Preserved ✅ 21ms
Event Format.Set Once Properties Preserved ✅ 21ms
Event Format.Groups Properties Preserved ✅ 25ms
Event Format.Sdk Generates Uuid If Not Provided ✅ 20ms
Event Format.Event Has Required Root Fields Batch ✅ 27ms
Event Format.Event Uuid Is Valid Batch ✅ 26ms
Event Format.Event Timestamp Is Rfc3339 Batch ✅ 25ms
Event Format.Distinct Id Is String Batch ✅ 25ms
Event Format.Distinct Id At Root Not Properties Batch ✅ 25ms
Event Format.Custom Properties Preserved Batch ✅ 24ms
Event Format.Set Properties Preserved Batch ✅ 23ms
Event Format.Set Once Properties Preserved Batch ✅ 27ms
Event Format.Groups Properties Preserved Batch ✅ 25ms
Event Format.Sdk Generates Uuid If Not Provided Batch ✅ 26ms
Batch Behavior.Multiple Events In Single Batch ✅ 35ms
Batch Behavior.Batch Envelope Smoke ✅ 31ms
Batch Behavior.Flush With No Events Sends Nothing ✅ 11ms
Batch Behavior.Flush At Triggers Batch ✅ 1019ms
Batch Behavior.Created At Reflects Batch Creation Time ✅ 22ms
Deduplication.Generates Unique Uuids ✅ 34ms
Deduplication.Different Events Same Content Different Uuids ✅ 20ms
Deduplication.Preserves Uuid On Retry ✅ 7012ms
Deduplication.Preserves Timestamp On Retry ✅ 7016ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7023ms
Deduplication.No Duplicate Events In Batch ✅ 31ms
Header Behavior On Retry.Attempt Header Starts At One ✅ 16ms
Header Behavior On Retry.Attempt Header Increments On Retry ✅ 12019ms
Header Behavior On Retry.Request Id Preserved On Retry ✅ 7016ms
Header Behavior On Retry.Different Requests Have Different Request Ids ✅ 2028ms
Header Behavior On Retry.Request Timestamp Changes On Retry ✅ 7017ms
Response Format Validation.Success Response Has Uuid Keyed Results ✅ 17ms
Response Format Validation.Success Response Has Ok For Each Event ✅ 20ms
Response Format Validation.Success No Retry After When All Ok ✅ 17ms
Response Format Validation.Success Retry After Present When Retry Events ✅ 18ms
Response Format Validation.Success No Retry After When Drop Only ✅ 19ms
Response Format Validation.Response Echoes Request Id ✅ 16ms
Retry Behavior.Retries On 408 ✅ 7012ms
Retry Behavior.Retries On 500 ✅ 7018ms
Retry Behavior.Retries On 503 ✅ 7022ms
Retry Behavior.Retries On 504 ✅ 7016ms
Retry Behavior.Retryable Errors Have Retry After ✅ 4014ms
Retry Behavior.Respects Retry After On Retryable Error ✅ 10018ms
Retry Behavior.Does Not Retry On 400 ✅ 4019ms
Retry Behavior.Does Not Retry On 401 ✅ 4018ms
Retry Behavior.Does Not Retry On 402 ✅ 4020ms
Retry Behavior.Does Not Retry On 413 ✅ 4019ms
Retry Behavior.Does Not Retry On 415 ✅ 4018ms
Retry Behavior.Non Retryable Errors Have No Retry After ✅ 4016ms
Retry Behavior.Implements Backoff ✅ 17033ms
Retry Behavior.Max Retries Respected ❌ 17034ms
Partial Batch Handling.Handles 200 Full Success ✅ 2017ms
Partial Batch Handling.Handles 200 With All Ok ✅ 3030ms
Partial Batch Handling.Does Not Retry Dropped Events ✅ 3024ms
Partial Batch Handling.Does Not Retry Limited Events ✅ 3025ms
Partial Batch Handling.Prunes Ok Events On Partial Retry ✅ 5028ms
Partial Batch Handling.Prunes Dropped Events On Partial Retry ✅ 5026ms
Partial Batch Handling.Retries Only Retry Events From Partial ✅ 5029ms
Partial Batch Handling.Partial Retry Preserves Uuids ✅ 5026ms
Partial Batch Handling.Partial Retry Attempt Header Increments ✅ 5026ms
Partial Batch Handling.Partial Retry Request Id Preserved ✅ 5022ms
Partial Batch Handling.Respects Retry After On Partial ✅ 5026ms
Partial Batch Handling.Unknown Result Treated As Terminal ✅ 3025ms
Partial Batch Handling.Mixed Ok Drop Limited No Retry ✅ 3035ms
Compression.Sends Gzip Content Encoding ✅ 16ms
Compression.No Content Encoding When Disabled ✅ 13ms
Compression.Compressed Body Is Decompressible ✅ 15ms
Error Handling.Does Not Retry On Unknown 4Xx ✅ 4017ms
Event Options.Cookieless Mode Override ✅ 17ms
Event Options.Disable Skew Correction Override ✅ 13ms
Event Options.Process Person Profile Override ✅ 15ms
Event Options.Product Tour Id Override ✅ 12ms
Event Options.Unset Options Omitted ✅ 13ms
Event Options.Options Override In Batch ✅ 17ms
Event Options.Unknown Option Passes Through ✅ 15ms
Event Options.Option Value Is Not Converted ✅ 13ms
Event Options.Lenient Bool Option Values Are Not Converted ✅ 13ms
Event Options.Option Wins Over Legacy Property ✅ 13ms
Event Options.Legacy Property Fills Unset Option ✅ 14ms
Event Options.Null Option Falls Back To Legacy Property ✅ 14ms
Geoip And Historical Migration.Geoip Disable Injected Into Properties ❌ 14ms
Geoip And Historical Migration.Historical Migration Set In Body ❌ 12ms
Geoip And Historical Migration.Historical Migration Absent By Default ✅ 13ms

Failures

event_format.non_utc_event_timestamp_is_converted_to_utc

Event 0 field 'timestamp' instant '2026-10-27T22:48:36.169Z' != expected '2025-01-02T03:04:05Z'

retry_behavior.max_retries_respected

Expected 4 requests, got 5

geoip_and_historical_migration.geoip_disable_injected_into_properties

Expected $geoip_disable='True', got 'None'. Available properties: ['$is_identified', '$recording_status', '$sdk_debug_pending_queue_size']

geoip_and_historical_migration.historical_migration_set_in_body

Body missing 'historical_migration' field. Body keys: ['created_at', 'batch']

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 35ms
Request Payload.Flags Request Uses V2 Query Param ✅ 22ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 19ms
Request Payload.Flags Request Omits Authorization Header ✅ 20ms
Request Payload.Token In Flags Body Matches Init ✅ 19ms
Request Payload.Groups Round Trip ✅ 16ms
Request Payload.Groups Default To Empty Object ✅ 20ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 15ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 15ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 17ms
Request Lifecycle.No Flags Request On Init Alone ✅ 7ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 21ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 34ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 21ms
Retry Behavior.Retries Flags On 502 ✅ 324ms
Retry Behavior.Retries Flags On 504 ✅ 321ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 17ms

Comment thread posthog/src/main/java/com/posthog/PostHog.kt Outdated
@veria-ai

veria-ai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

@turnipdabeets
turnipdabeets force-pushed the feat/v4-capture-options branch from 6d338e3 to 840c59b Compare October 27, 2026 15:53
@turnipdabeets
turnipdabeets force-pushed the feat/v4-capture-options branch from 840c59b to 43ac7c5 Compare October 27, 2026 16:44
turnipdabeets and others added 2 commits October 27, 2026 13:06
`capture`, `screen`, `identify`, `setPersonProperties`, `alias`, `group` and
`captureException` take an `options` map that is copied onto the new
`PostHogEvent.options`, so PostHog can be told how to process one event apart
from its properties and `beforeSend` can edit it.

Properties are merged in one order: SDK-set values, registered super
properties, the caller's properties (with `$set`, `$set_once` and `$groups`
as per-call values), then `beforeSend`. `$is_identified`,
`$process_person_profile` and the replay debug properties are no longer
re-applied after the caller's values.

The SDK sets the `process_person_profile` option to `false` only when person
processing is off, and only when neither a caller option nor a caller or
registered `$process_person_profile` property already says so. It no longer
writes a `$process_person_profile` property.

Also: a blank `distinctId` argument on `capture` uses the current distinct id;
a `$set` sent with `process_person_profile: false` neither stores nor matches
the person-properties hash; an event returned by `beforeSend` keeps the uuid of
the client capture it came from; the minimal `$feature_flag_called` allowlist
keeps `$cookieless_mode`, `$ignore_sent_at` and `$product_tour_id`; the
compliance adapter forwards `options` and advertises `event_options`.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DRbQPidntd4hVufNpMT19L

@dustinbyrne dustinbyrne left a comment

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.

The deep-link correction resolves the automatic processing override. One person-processing regression remains: a null legacy value can suppress the personless default. There are also two Kotlin migration expressions to escape.

AI-assisted review.

Comment thread posthog/src/main/java/com/posthog/PostHog.kt Outdated
Comment thread docs/migration-3.x-to-4.0.md Outdated
@dustinbyrne
dustinbyrne requested a review from a team October 27, 2026 21:31
turnipdabeets and others added 17 commits October 27, 2026 18:43
A Java caller can pass a null `$process_person_profile`. It no longer counts as an override, so the SDK still sends `process_person_profile: false` when person processing is off.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`captureAi` takes the same arguments as `capture`, goes through the same
enrichment, precedence, personless default and `beforeSend`, and queues the
event on its own disk queue, executor and retry identity for
`POST /i/v1/ai/events`. It returns the event's uuid once it's handed to the
queue, or null when the SDK is disabled or opted out or `beforeSend` dropped
it. A name not starting with `$ai_` logs one debug line and is sent unchanged;
`capture` never reroutes `$ai_*` events. The AI request client uses
`captureAiTimeout` for its call, read and write timeouts and honors
`captureAiCompression` through its own gzip interceptor instance.

`PostHogQueue` becomes byte-aware through `EndpointSpec`: `maxBatchBytes`
bounds a request window (check before append, an oversize record goes alone)
and flushes as soon as that much is queued; `maxQueueBytes` is a FIFO disk cap
on top of `maxQueueSize`, enforced on add and on load; `maxRecordBytes` drops a
record over the limit when it's queued, logging only its name and size. The
analytics spec gets a 5 MiB request cap; the AI spec gets 5 MiB requests,
50 MiB on disk and `captureAiMaxEventBytes` (at most 8 MiB) plus a 64 KiB
envelope per event.

New `PostHogConfig` knobs: `captureAiCompression`, `captureAiMaxQueueSize`,
`captureAiTimeout` and `captureAiMaxEventBytes`; non-positive values use the
defaults. `PostHogAndroid` stores the AI queue under `posthog-disk-ai-queue`.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DRbQPidntd4hVufNpMT19L
SDK-level: routing by method, beforeSend and options, null returns, a
terminal 404, the oversize drop (name and size only in the log), the non-`$ai_`
debug line, flush and close draining the AI queue, compression per lane and the
AI timeout. API-level: the AI endpoint's headers and body, separate retry
identities per lane, and an AI queue keeping only the events asked to retry.
Queue-level, on a synthetic record: byte-limited request windows, an oversize
record sent alone, the flush at a request's worth of bytes, the per-record
drop, the disk cap on add and on load, and the spec limits and config
fallbacks. The Android setup test covers the AI storage prefix.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DRbQPidntd4hVufNpMT19L
Adds `POST /capture_ai`, which routes through `captureAi` and returns the uuid
it sent, tracks `/i/v1/ai/events` requests next to the analytics ones and
advertises `capture_ai_v1`. Also restores the capture v1 adapter changes
(tracking by capture path, `PostHog-Attempt` as the retry count,
`personProfiles = ALWAYS`, the renamed push retries field) that the options
commit reverted.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DRbQPidntd4hVufNpMT19L
The queue measured an AI event after `encryption`, so an encryption that
grows the data dropped events PostHog would accept, and captureAi had
already returned the uuid. captureAi now measures the serialized event
before encryption and returns null when it's over the limit. The queue's
per-record limit had no other user and is removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The limit covers an AI event's properties up to 8 MiB, with 64 KiB for the
rest of the serialized event, measured before encryption. captureAiTimeout
is a timeout without network activity, not a call timeout.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Debug logs named only the drop count, so a misrouted_event or
ai_event_too_big drop was invisible. Each dropped event is now logged with
its name, uuid and the server's details, never its properties. Adds a test
that an AI event with exactly 8 MiB of properties is sent.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
captureAi checks the size on the caller's thread, so a huge prompt or
base64 payload no longer costs a full serialization just to be dropped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Properties can hold prompts and other user content.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
java.util.Base64 isn't on API 23, so animalsnifferTest failed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The data class hashCode calls Double.hashCode(double), which isn't on API 23.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@dustinbyrne dustinbyrne left a comment

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.

Both earlier findings are fixed: null legacy person-processing values retain the personless default, and the Kotlin migration examples compile. I rechecked the updated implementation and tests and found no additional issues.

AI-assisted review.

turnipdabeets and others added 5 commits October 28, 2026 16:14
* fix: retry capture v1 requests that get 404 or 429

A 404 usually means a misconfigured proxy and a 429 now only comes from an overloaded ingress, so keep the events queued and retry them with the usual backoff and Retry-After handling instead of dropping them. Matches PostHog/posthog-go#395.

* fix: warn once when capture v1 returns 404

A 404 now keeps events queued, so nothing tells the app that the route
is missing. Print one warning per client, even without debug, naming the
URL and the path a reverse proxy or self-hosted instance must serve.

* fix: leave host credentials and query out of the capture v1 404 warning

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Match posthog-ios, posthog-python and the Flutter desktop lane: the value
is the serialized event size, defaulting to 8 MiB + 64 KiB, instead of a
properties size the SDK added 64 KiB to. A value over the ceiling now
logs a warning when it is clamped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@turnipdabeets
turnipdabeets merged commit 3106d18 into main Oct 28, 2026
@turnipdabeets
turnipdabeets deleted the feat/v4-capture-options branch October 28, 2026 20:59

@posthog posthog Bot left a comment

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.

PostHog Review · Standard · reviewed 83e9b67: 2 Should fix, 1 Consider. This pull request is large, so the review ran in 4 parts with less depth than usual.

Comment thread posthog/src/main/java/com/posthog/internal/PostHogQueue.kt
Comment thread posthog/src/main/java/com/posthog/PostHog.kt
Comment thread posthog/src/main/java/com/posthog/PostHog.kt
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.

2 participants