Skip to content

fix: keep $lib and $lib_version on capture v1 events - #1036

Merged
turnipdabeets merged 1 commit into
chore/v4-remove-deprecatedfrom
fix/v4-keep-lib-props
Nov 5, 2026
Merged

turnipdabeets merged 1 commit into
chore/v4-remove-deprecatedfrom
fix/v4-keep-lib-props

Conversation

@turnipdabeets

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

Capture v1 currently deletes $lib/$lib_version from each event before sending, and PostHog fills them from the PostHog-Sdk-Info header. That header carries the SDK version running at send time, so an event queued offline and sent after an app update gets the new version. 4.0 also sends events 3.x left on disk, so those get labeled 4.0.

Per the capture v1 thread, we're keeping per-event $lib/$lib_version and having ingestion store them as sent. This PR stops deleting them in captureV1JSON (PostHogApi.swift), so 4.0 sends them like 3.x did. They stay visible and changeable in beforeSend.

Until capture-rs stops overwriting them from the header, PostHog stores the same values as before this PR. The behavior changes once that backend change lands.

Docs: removed the breaking-change entry from the changeset and the "SDK identity" section and checklist line from MIGRATION.md, since 3.x behavior is back.

💚 How did you test it?

  • PostHogCaptureV1Test buildsV1Body now checks a stored $lib_version: 1.0.0 is sent as-is while PostHog-Sdk-Info carries the running version. The test mock server no longer fills $lib/$lib_version from the header, so event assertions see what the SDK sent.
  • Re-recorded event-shapes-batch.json: all 5 events now carry $lib/$lib_version.
  • With the old code put back, the changed tests fail; with this change they pass.
  • swift test: all pass except 13 App Group issues in PostHogStorageTest, which fail the same way on the base branch. make swiftFormatCheck clean; make swiftLintCheck has no serious violations.

📝 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.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Claude Code (Claude Opus 5.5). Scope kept to the send step; the SDK already sets $lib/$lib_version at capture time, so no new injection point.
  • Removed the docs entry rather than rewording it, because the SDK now matches 3.x.

🤖 Generated with Claude Code

An event queued before an SDK upgrade keeps the version that captured it instead of getting the running version from PostHog-Sdk-Info.
@turnipdabeets turnipdabeets self-assigned this Nov 5, 2026
@turnipdabeets
turnipdabeets marked this pull request as ready for review November 5, 2026 19:26
@turnipdabeets
turnipdabeets requested a review from a team as a code owner November 5, 2026 19:26
@turnipdabeets turnipdabeets mentioned this pull request Nov 5, 2026
6 of 18 tasks
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

posthog-ios Compliance Report

Date: 2026-11-05T19:39:29.254171+00:00
Duration: 1009547ms

✅ All Tests Passed!

234/234 tests passed


Capture_V1 Tests

✅ 106/106 tests passed

View Details
Test Status Duration
Endpoint And Method.Targets V1 Endpoint ✅ 2844ms
Endpoint And Method.Does Not Use Legacy Endpoints ✅ 2775ms
Required Headers.Has Authorization Bearer Header ✅ 2820ms
Required Headers.Has Content Type Json ✅ 2894ms
Required Headers.Has Posthog Sdk Info Format ✅ 2954ms
Required Headers.Has Posthog Attempt Header ✅ 343ms
Required Headers.Has Posthog Request Id ✅ 2819ms
Required Headers.Has Posthog Request Timestamp ✅ 2725ms
Required Headers.Has User Agent ✅ 2742ms
Body Format.Body Has Created At And Batch ✅ 330ms
Body Format.No Api Key In Body ✅ 2861ms
Body Format.No Sent At In Body ✅ 2721ms
Event Format.Event Has Required Root Fields ✅ 2646ms
Event Format.Event Uuid Is Valid ✅ 2721ms
Event Format.Event Timestamp Is Rfc3339 ✅ 2859ms
Event Format.Non Utc Event Timestamp Is Converted To Utc ✅ 2750ms
Event Format.Distinct Id Is String ✅ 2781ms
Event Format.Distinct Id At Root Not Properties ✅ 2867ms
Event Format.Custom Properties Preserved ✅ 2896ms
Event Format.Set Properties Preserved ✅ 2868ms
Event Format.Set Once Properties Preserved ✅ 2941ms
Event Format.Groups Properties Preserved ✅ 2926ms
Event Format.Sdk Generates Uuid If Not Provided ✅ 2851ms
Event Format.Event Has Required Root Fields Batch ✅ 3002ms
Event Format.Event Uuid Is Valid Batch ✅ 2971ms
Event Format.Event Timestamp Is Rfc3339 Batch ✅ 2950ms
Event Format.Distinct Id Is String Batch ✅ 2931ms
Event Format.Distinct Id At Root Not Properties Batch ✅ 2884ms
Event Format.Custom Properties Preserved Batch ✅ 3004ms
Event Format.Set Properties Preserved Batch ✅ 3215ms
Event Format.Set Once Properties Preserved Batch ✅ 3229ms
Event Format.Groups Properties Preserved Batch ✅ 3427ms
Event Format.Sdk Generates Uuid If Not Provided Batch ✅ 3132ms
Batch Behavior.Multiple Events In Single Batch ✅ 3673ms
Batch Behavior.Batch Envelope Smoke ✅ 3152ms
Batch Behavior.Flush With No Events Sends Nothing ✅ 435ms
Batch Behavior.Flush At Triggers Batch ✅ 1403ms
Batch Behavior.Created At Reflects Batch Creation Time ✅ 2824ms
Deduplication.Generates Unique Uuids ✅ 3309ms
Deduplication.Different Events Same Content Different Uuids ✅ 2731ms
Deduplication.Preserves Uuid On Retry ✅ 5431ms
Deduplication.Preserves Timestamp On Retry ✅ 9284ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7859ms
Deduplication.No Duplicate Events In Batch ✅ 2947ms
Header Behavior On Retry.Attempt Header Starts At One ✅ 3047ms
Header Behavior On Retry.Attempt Header Increments On Retry ✅ 16794ms
Header Behavior On Retry.Request Id Preserved On Retry ✅ 9355ms
Header Behavior On Retry.Different Requests Have Different Request Ids ✅ 7468ms
Header Behavior On Retry.Request Timestamp Changes On Retry ✅ 9461ms
Response Format Validation.Success Response Has Uuid Keyed Results ✅ 2836ms
Response Format Validation.Success Response Has Ok For Each Event ✅ 2753ms
Response Format Validation.Success No Retry After When All Ok ✅ 2865ms
Response Format Validation.Success Retry After Present When Retry Events ✅ 2969ms
Response Format Validation.Success No Retry After When Drop Only ✅ 2994ms
Response Format Validation.Response Echoes Request Id ✅ 2771ms
Retry Behavior.Retries On 408 ✅ 8772ms
Retry Behavior.Retries On 500 ✅ 9234ms
Retry Behavior.Retries On 503 ✅ 11354ms
Retry Behavior.Retries On 504 ✅ 9236ms
Retry Behavior.Retries On 404 ✅ 8910ms
Retry Behavior.Retries On 429 ✅ 5411ms
Retry Behavior.Retries On 502 ✅ 8894ms
Retry Behavior.Retryable Errors Have Retry After ✅ 6308ms
Retry Behavior.Respects Retry After On Retryable Error ✅ 10925ms
Retry Behavior.Does Not Retry On 400 ✅ 4751ms
Retry Behavior.Does Not Retry On 401 ✅ 4838ms
Retry Behavior.Does Not Retry On 402 ✅ 4937ms
Retry Behavior.Does Not Retry On 413 ✅ 4935ms
Retry Behavior.Does Not Retry On 415 ✅ 5001ms
Retry Behavior.Non Retryable Errors Have No Retry After ✅ 2440ms
Retry Behavior.Implements Backoff ✅ 17924ms
Partial Batch Handling.Handles 200 Full Success ✅ 4872ms
Partial Batch Handling.Handles 200 With All Ok ✅ 6097ms
Partial Batch Handling.Does Not Retry Dropped Events ✅ 6001ms
Partial Batch Handling.Does Not Retry Warning Events ✅ 6050ms
Partial Batch Handling.Prunes Ok Events On Partial Retry ✅ 7951ms
Partial Batch Handling.Prunes Dropped Events On Partial Retry ✅ 7985ms
Partial Batch Handling.Retries Only Retry Events From Partial ✅ 8033ms
Partial Batch Handling.Partial Retry Preserves Uuids ✅ 7975ms
Partial Batch Handling.Partial Retry Attempt Header Increments ✅ 7924ms
Partial Batch Handling.Partial Retry Request Id Preserved ✅ 7849ms
Partial Batch Handling.Respects Retry After On Partial ✅ 7978ms
Partial Batch Handling.Unknown Result Treated As Terminal ✅ 5914ms
Partial Batch Handling.Mixed Ok Drop Warning No Retry ✅ 5952ms
Compression.Sends Gzip Content Encoding ✅ 2813ms
Compression.No Content Encoding When Disabled ✅ 501ms
Compression.Compressed Body Is Decompressible ✅ 2740ms
Error Handling.Does Not Retry On Unknown 4Xx ✅ 5270ms
Event Options.Cookieless Mode Override ✅ 2865ms
Event Options.Disable Skew Correction Override ✅ 2833ms
Event Options.Process Person Profile Override ✅ 2850ms
Event Options.Product Tour Id Override ✅ 2858ms
Event Options.Unset Options Omitted ✅ 2871ms
Event Options.Options Override In Batch ✅ 2957ms
Event Options.Unknown Option Passes Through ✅ 2872ms
Event Options.Option Value Is Not Converted ✅ 2815ms
Event Options.Lenient Bool Option Values Are Not Converted ✅ 2879ms
Event Options.Option Wins Over Legacy Property ✅ 2726ms
Event Options.Legacy Property Fills Unset Option ✅ 2772ms
Event Options.Null Option Falls Back To Legacy Property ✅ 2900ms
Property Layers.Caller Property Beats Registered Property ✅ 2859ms
Property Layers.Before Send Runs Last ✅ 2764ms
Fail Open.Empty Api Key Sends Nothing ✅ 1272ms
Fail Open.Personal Api Key Sends Nothing ✅ 1278ms
Geoip And Historical Migration.Geoip Disable Injected Into Properties ✅ 2952ms
Geoip And Historical Migration.Historical Migration Absent By Default ✅ 2885ms

Capture_Ai_V1 Tests

✅ 111/111 tests passed

View Details
Test Status Duration
Endpoint And Method.Targets V1 Endpoint ✅ 2945ms
Endpoint And Method.Does Not Use Legacy Endpoints ✅ 452ms
Endpoint And Method.Capture Does Not Reroute Ai Named Events ✅ 2883ms
Endpoint And Method.Capture Ai Does Not Reroute Non Ai Events ✅ 450ms
Lane Isolation.Failing Ai Lane Does Not Delay Analytics ✅ 11733ms
Required Headers.Has Authorization Bearer Header ✅ 2743ms
Required Headers.Has Content Type Json ✅ 2869ms
Required Headers.Has Posthog Sdk Info Format ✅ 2821ms
Required Headers.Has Posthog Attempt Header ✅ 2879ms
Required Headers.Has Posthog Request Id ✅ 2789ms
Required Headers.Has Posthog Request Timestamp ✅ 2968ms
Required Headers.Has User Agent ✅ 2870ms
Body Format.Body Has Created At And Batch ✅ 2892ms
Body Format.No Api Key In Body ✅ 2903ms
Body Format.No Sent At In Body ✅ 410ms
Event Format.Event Has Required Root Fields ✅ 2779ms
Event Format.Event Uuid Is Valid ✅ 2939ms
Event Format.Event Timestamp Is Rfc3339 ✅ 2869ms
Event Format.Non Utc Event Timestamp Is Converted To Utc ✅ 2921ms
Event Format.Distinct Id Is String ✅ 2913ms
Event Format.Distinct Id At Root Not Properties ✅ 2870ms
Event Format.Custom Properties Preserved ✅ 2730ms
Event Format.Set Properties Preserved ✅ 2865ms
Event Format.Set Once Properties Preserved ✅ 2901ms
Event Format.Groups Properties Preserved ✅ 2866ms
Event Format.Sdk Generates Uuid If Not Provided ✅ 2875ms
Event Format.Event Has Required Root Fields Batch ✅ 3001ms
Event Format.Event Uuid Is Valid Batch ✅ 2924ms
Event Format.Event Timestamp Is Rfc3339 Batch ✅ 2805ms
Event Format.Distinct Id Is String Batch ✅ 2800ms
Event Format.Distinct Id At Root Not Properties Batch ✅ 2958ms
Event Format.Custom Properties Preserved Batch ✅ 2876ms
Event Format.Set Properties Preserved Batch ✅ 3015ms
Event Format.Set Once Properties Preserved Batch ✅ 2947ms
Event Format.Groups Properties Preserved Batch ✅ 3033ms
Event Format.Sdk Generates Uuid If Not Provided Batch ✅ 3000ms
Batch Behavior.Multiple Events In Single Batch ✅ 3002ms
Batch Behavior.Batch Envelope Smoke ✅ 2897ms
Batch Behavior.Flush At Triggers Batch ✅ 1215ms
Batch Behavior.Created At Reflects Batch Creation Time ✅ 386ms
Deduplication.Generates Unique Uuids ✅ 3288ms
Deduplication.Different Events Same Content Different Uuids ✅ 3007ms
Deduplication.Preserves Uuid On Retry ✅ 9275ms
Deduplication.Preserves Timestamp On Retry ✅ 9440ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7840ms
Deduplication.No Duplicate Events In Batch ✅ 3030ms
Header Behavior On Retry.Attempt Header Starts At One ✅ 2848ms
Header Behavior On Retry.Attempt Header Increments On Retry ✅ 14412ms
Header Behavior On Retry.Request Id Preserved On Retry ✅ 9251ms
Header Behavior On Retry.Different Requests Have Different Request Ids ✅ 7768ms
Header Behavior On Retry.Request Timestamp Changes On Retry ✅ 5476ms
Response Format Validation.Success Response Has Uuid Keyed Results ✅ 2759ms
Response Format Validation.Success Response Has Ok For Each Event ✅ 3001ms
Response Format Validation.Success No Retry After When All Ok ✅ 2897ms
Response Format Validation.Success Retry After Present When Retry Events ✅ 2946ms
Response Format Validation.Success No Retry After When Drop Only ✅ 3003ms
Response Format Validation.Response Echoes Request Id ✅ 2819ms
Retry Behavior.Retries On 408 ✅ 9343ms
Retry Behavior.Retries On 500 ✅ 9303ms
Retry Behavior.Retries On 503 ✅ 5457ms
Retry Behavior.Retries On 504 ✅ 5442ms
Retry Behavior.Retries On 404 ✅ 8935ms
Retry Behavior.Retries On 429 ✅ 8842ms
Retry Behavior.Retries On 502 ✅ 8724ms
Retry Behavior.Retryable Errors Have Retry After ✅ 5922ms
Retry Behavior.Respects Retry After On Retryable Error ✅ 10832ms
Retry Behavior.Does Not Retry On 400 ✅ 4736ms
Retry Behavior.Does Not Retry On 401 ✅ 2435ms
Retry Behavior.Does Not Retry On 402 ✅ 4746ms
Retry Behavior.Does Not Retry On 413 ✅ 4825ms
Retry Behavior.Does Not Retry On 415 ✅ 4987ms
Retry Behavior.Non Retryable Errors Have No Retry After ✅ 4889ms
Retry Behavior.Implements Backoff ✅ 18392ms
Partial Batch Handling.Handles 200 Full Success ✅ 4753ms
Partial Batch Handling.Handles 200 With All Ok ✅ 6000ms
Partial Batch Handling.Does Not Retry Dropped Events ✅ 5857ms
Partial Batch Handling.Does Not Retry Warning Events ✅ 5881ms
Partial Batch Handling.Prunes Ok Events On Partial Retry ✅ 8008ms
Partial Batch Handling.Prunes Dropped Events On Partial Retry ✅ 7886ms
Partial Batch Handling.Retries Only Retry Events From Partial ✅ 8008ms
Partial Batch Handling.Partial Retry Preserves Uuids ✅ 7939ms
Partial Batch Handling.Partial Retry Attempt Header Increments ✅ 7883ms
Partial Batch Handling.Partial Retry Request Id Preserved ✅ 7898ms
Partial Batch Handling.Respects Retry After On Partial ✅ 7869ms
Partial Batch Handling.Unknown Result Treated As Terminal ✅ 6004ms
Partial Batch Handling.Mixed Ok Drop Warning No Retry ✅ 5992ms
Compression.Sends Gzip Content Encoding ✅ 2875ms
Compression.No Content Encoding When Disabled ✅ 2904ms
Compression.Compressed Body Is Decompressible ✅ 2816ms
Error Handling.Does Not Retry On Unknown 4Xx ✅ 4909ms
Event Options.Cookieless Mode Override ✅ 2860ms
Event Options.Disable Skew Correction Override ✅ 2882ms
Event Options.Process Person Profile Override ✅ 2876ms
Event Options.Product Tour Id Override ✅ 2880ms
Event Options.Unset Options Omitted ✅ 440ms
Event Options.Options Override In Batch ✅ 3030ms
Event Options.Unknown Option Passes Through ✅ 2833ms
Event Options.Option Value Is Not Converted ✅ 2867ms
Event Options.Lenient Bool Option Values Are Not Converted ✅ 518ms
Event Options.Option Wins Over Legacy Property ✅ 2895ms
Event Options.Legacy Property Fills Unset Option ✅ 450ms
Event Options.Null Option Falls Back To Legacy Property ✅ 2957ms
Event Size.Event Over Ceiling Is Not Sent ✅ 7351ms
Event Size.Over Ceiling Drop Is Reported Or Logged Without Content ✅ 3050ms
Event Size.Batches Close Before Byte Target ✅ 9285ms
Geoip And Historical Migration.Geoip Disable Injected Into Properties ✅ 2938ms
Geoip And Historical Migration.Historical Migration Absent By Default ✅ 2819ms
Property Layers.Caller Property Beats Registered Property ✅ 2903ms
Property Layers.Before Send Runs Last ✅ 2827ms
Fail Open.Empty Api Key Sends Nothing ✅ 1320ms
Fail Open.Personal Api Key Sends Nothing ✅ 1382ms

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 2910ms
Request Payload.Flags Request Uses V2 Query Param ✅ 2920ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 3022ms
Request Payload.Flags Request Omits Authorization Header ✅ 3020ms
Request Payload.Token In Flags Body Matches Init ✅ 3071ms
Request Payload.Groups Round Trip ✅ 2936ms
Request Payload.Groups Default To Empty Object ✅ 2891ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 2844ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 2876ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 2873ms
Request Lifecycle.No Flags Request On Init Alone ✅ 110ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 438ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 5609ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 2819ms
Retry Behavior.Retries Flags On 502 ✅ 2870ms
Retry Behavior.Retries Flags On 504 ✅ 2898ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 3109ms

turnipdabeets added a commit to PostHog/posthog-flutter that referenced this pull request Nov 5, 2026
posthog-ios keeps per-event $lib and $lib_version on capture v1
(PostHog/posthog-ios#1036), so iOS and macOS no longer drop them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@turnipdabeets
turnipdabeets merged commit 436fd50 into chore/v4-remove-deprecated Nov 5, 2026
49 checks passed
@turnipdabeets
turnipdabeets deleted the fix/v4-keep-lib-props branch November 5, 2026 22:58
gewenyu99 added a commit that referenced this pull request Nov 6, 2026
Rebuilt from MIGRATION.md on chore/v4-remove-deprecated, which dropped the
SDK identity section (#1036) and added the isFeatureEnabled empty-variant note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gewenyu99 added a commit that referenced this pull request Nov 11, 2026
* docs: add the generated SDK reference for 3.x

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: add the generated SDK reference for 4.x (experimental)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS references from the DocC archive

The 4.x page and migration guide come from chore/v4-remove-deprecated (the 4.0
branch) with the capability tags and getting-started applied. Both still need to
land there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS references with deprecations and Swift-only symbols

3.x and 4.x now mark deprecated APIs and give same-titled overloads one heading.
4.x drops the Swift-obsoleted ObjC bridges, lists captureAi, alias(_:options:) and
isFeatureEnabled(_:defaultValue:) under their capabilities, and installs with
Swift Package Manager only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS references from docs/capabilities.json

The pages match the tag-based run, minus six empty Discussion headings that a
discussion holding only the tag line left behind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS migration page from the current 4.0 guide

Rebuilt from MIGRATION.md on chore/v4-remove-deprecated, which dropped the
SDK identity section (#1036) and added the isFeatureEnabled empty-variant note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS migration page from the current 4.0 guide

Rebuilt from MIGRATION.md on chore/v4-remove-deprecated after its
pre-release review fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the iOS 4.x page from chore/v4-remove-deprecated

Picks up the branch's feature flag doc comment fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: regenerate the references with the getting-started intro

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
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