Skip to content

fix: omit null-valued event properties - #1047

Merged
turnipdabeets merged 2 commits into
chore/v4-remove-deprecatedfrom
fix/v4-drop-null-properties
Nov 9, 2026
Merged

turnipdabeets merged 2 commits into
chore/v4-remove-deprecatedfrom
fix/v4-drop-null-properties

Conversation

@turnipdabeets

@turnipdabeets turnipdabeets commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

sdk-specs capture requires Capture drops null-valued object properties, and capture-ai requires captureAi to follow it. iOS sent NSNull() property values as JSON null, on the wire and in the disk queue. This is the only gap on the iOS Capture and Capture AI compliance rows in sdk-specs #187. Android and Flutter already drop these.

Changes

  • Analytics and AI events drop NSNull (and nil boxed in Any) property values when they're written to the disk queue and again when they're sent, after beforeSend. The send-time pass also cleans events queued by older versions.
  • Recursive into nested dictionaries and dictionaries inside arrays. Null array elements stay at their index, emptied dictionaries stay {}, and false, 0, "", "null" and empty containers are unchanged.
  • Covers every event that goes through the analytics or AI queue: capture, captureAi, screen, captureException, $feature_flag_called, and so on. Session replay snapshots aren't touched.
  • No API change: callers can still pass NSNull().
  • Changeset bullet in the 4.0 release notes and a short MIGRATION.md section.

Scope choice on $set / $set_once / $group_set: the spec covers "custom event object properties" and says nothing about person or group properties. An iOS caller may pass $set: ["plan": NSNull()] to clear a person property, so these three keys are left as given, and a test pins that.

Behavior change worth noting: SDK-set nulls are dropped too. $feature_flag_called for a flag with no value now has no $feature_flag_response instead of null. That matches posthog-js, which leaves it undefined. One existing test was updated for this.

Performance: one extra pass over the properties at enqueue and at send. Unchanged containers aren't copied. A local benchmark on an extreme payload (10k top-level properties plus 2,000 message dictionaries) took about 15 ms per pass, mostly the existing isNullValue boxed-nil check.

💚 How did you test it?

New Capture V1 null properties suite (PostHogCaptureNullPropertiesTest) in PostHogCaptureV1Test.swift, built on the spec scenarios. It covers capture, captureAi, nulls added by beforeSend, the disk encoding of the analytics and AI queues, dictionaries with non-string keys, events queued before this change being cleaned on send, and $set/$set_once/$group_set nulls being kept.

iOS simulator (iPhone Air, iOS 26.4.1). xcodebuild test hung before connecting on this machine ("The test runner hung before establishing connection"), so I built the bundle and ran it inside the simulator:

xcrun xcodebuild build-for-testing -scheme PostHog -destination 'id=EC5B8EC0-09FD-42D0-91C2-55E94EF91DD2' -derivedDataPath <dd>
xcrun simctl boot EC5B8EC0-09FD-42D0-91C2-55E94EF91DD2
X=$(xcode-select -p)/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Agents/xctest
B=<dd>/Build/Products/Testing-iphonesimulator/PostHogTests.xctest
xcrun simctl spawn EC5B8EC0-09FD-42D0-91C2-55E94EF91DD2 "$X" -XCTest PostHogTests.PostHogCaptureNullPropertiesTest "$B"
xcrun simctl spawn EC5B8EC0-09FD-42D0-91C2-55E94EF91DD2 "$X" -XCTest All "$B"
Run Result
New suite, this branch (0ce74f425) 7/7 passed
New suite, base 05721bbdc with only PostHogCaptureV1Test.swift from this branch 6 of 7 failed as expected (13 issues: test/hookNull present, nested {"drop":null} kept, {"1":null} stored). The $set/$set_once/$group_set guard passes before and after.
Full bundle (-XCTest All), this branch 1,822 tests in 246 suites: 1 failure, "registered and caller process_person_profile properties and options beat the SDK's", which timed out waiting for the mock server. That suite (PostHogCaptureV1OptionsTest) then passed 18/18 when rerun on its own. The test doesn't involve null values, and it passes in CI.

App smoke test on the same simulator. The PostHogExample app was temporarily pointed at a local capture server (that change isn't committed). It called capture and captureAi with NSNull() values at the top level, in a nested dictionary, in an array, and in a dictionary inside an array, plus $set: ["plan": NSNull()]. Both /i/v1/analytics/events and /i/v1/ai/events received test absent, nested: {"keep": 1}, items: ["1", null, 2, {}, [null]], ""/0/false/"null"/[] unchanged, and $set: {"plan": null}.

macOS SPM:

  • make test filter="'PostHogCaptureNullPropertiesTest|PostHogPropertiesSerializationTests|PostHogCaptureV1Test|UtilsTest'": 116/116 passed.
  • The isFeatureEnabledDoesNotReportDefault test was updated because $feature_flag_response is now absent instead of null. It passes.
  • Full make test ran while other test runs shared the machine and failed in unrelated suites. The two app-group PostHogStorageTest cases fail the same way on the base branch, and the rest passed when rerun on their own.
  • make lint: passes. The warnings it prints are already on the base branch.
  • CI: all checks pass, including SDK compliance (234/234).

📝 Checklist

  • All commits are signed (see Commit signing)
  • 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 (added a bullet to the existing 4.0 changeset)

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Claude Code (Opus 5.5) implemented this from the sdk-specs requirement, following the scope set by the requester. It encodes in two places, at enqueue and at send, so that both the disk queue and events left over from older versions meet the spec.

🤖 Generated with Claude Code

Drop properties whose value is NSNull (or a nil boxed in Any) from analytics
and AI events when they are written to the queue and again when they are
sent, recursing into nested dictionaries and dictionaries inside arrays.
Null array elements keep their index and emptied dictionaries stay {}.
$set, $set_once and $group_set values are left as given so a caller can
still clear a person or group property.

Implements the sdk-specs capture requirement "Capture drops null-valued
object properties" and capture-ai's matching requirement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@turnipdabeets turnipdabeets self-assigned this Nov 9, 2026
@turnipdabeets
turnipdabeets marked this pull request as ready for review November 9, 2026 18:05
@turnipdabeets
turnipdabeets requested a review from a team as a code owner November 9, 2026 18:05
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

posthog-ios Compliance Report

Date: 2026-11-09T18:36:02.603191+00:00
Duration: 976559ms

✅ 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 ✅ 2725ms
Endpoint And Method.Does Not Use Legacy Endpoints ✅ 416ms
Required Headers.Has Authorization Bearer Header ✅ 2750ms
Required Headers.Has Content Type Json ✅ 2665ms
Required Headers.Has Posthog Sdk Info Format ✅ 2797ms
Required Headers.Has Posthog Attempt Header ✅ 2771ms
Required Headers.Has Posthog Request Id ✅ 2728ms
Required Headers.Has Posthog Request Timestamp ✅ 2726ms
Required Headers.Has User Agent ✅ 2783ms
Body Format.Body Has Created At And Batch ✅ 2665ms
Body Format.No Api Key In Body ✅ 2699ms
Body Format.No Sent At In Body ✅ 2765ms
Event Format.Event Has Required Root Fields ✅ 2799ms
Event Format.Event Uuid Is Valid ✅ 2689ms
Event Format.Event Timestamp Is Rfc3339 ✅ 395ms
Event Format.Non Utc Event Timestamp Is Converted To Utc ✅ 2750ms
Event Format.Distinct Id Is String ✅ 2732ms
Event Format.Distinct Id At Root Not Properties ✅ 2700ms
Event Format.Custom Properties Preserved ✅ 2728ms
Event Format.Set Properties Preserved ✅ 254ms
Event Format.Set Once Properties Preserved ✅ 2818ms
Event Format.Groups Properties Preserved ✅ 2777ms
Event Format.Sdk Generates Uuid If Not Provided ✅ 2719ms
Event Format.Event Has Required Root Fields Batch ✅ 2769ms
Event Format.Event Uuid Is Valid Batch ✅ 2777ms
Event Format.Event Timestamp Is Rfc3339 Batch ✅ 2824ms
Event Format.Distinct Id Is String Batch ✅ 2754ms
Event Format.Distinct Id At Root Not Properties Batch ✅ 2712ms
Event Format.Custom Properties Preserved Batch ✅ 2743ms
Event Format.Set Properties Preserved Batch ✅ 2921ms
Event Format.Set Once Properties Preserved Batch ✅ 2872ms
Event Format.Groups Properties Preserved Batch ✅ 2764ms
Event Format.Sdk Generates Uuid If Not Provided Batch ✅ 2839ms
Batch Behavior.Multiple Events In Single Batch ✅ 2867ms
Batch Behavior.Batch Envelope Smoke ✅ 2761ms
Batch Behavior.Flush With No Events Sends Nothing ✅ 301ms
Batch Behavior.Flush At Triggers Batch ✅ 1165ms
Batch Behavior.Created At Reflects Batch Creation Time ✅ 2681ms
Deduplication.Generates Unique Uuids ✅ 2874ms
Deduplication.Different Events Same Content Different Uuids ✅ 2860ms
Deduplication.Preserves Uuid On Retry ✅ 9273ms
Deduplication.Preserves Timestamp On Retry ✅ 9216ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7813ms
Deduplication.No Duplicate Events In Batch ✅ 2827ms
Header Behavior On Retry.Attempt Header Starts At One ✅ 2625ms
Header Behavior On Retry.Attempt Header Increments On Retry ✅ 16711ms
Header Behavior On Retry.Request Id Preserved On Retry ✅ 8817ms
Header Behavior On Retry.Different Requests Have Different Request Ids ✅ 7280ms
Header Behavior On Retry.Request Timestamp Changes On Retry ✅ 9199ms
Response Format Validation.Success Response Has Uuid Keyed Results ✅ 2729ms
Response Format Validation.Success Response Has Ok For Each Event ✅ 2797ms
Response Format Validation.Success No Retry After When All Ok ✅ 2851ms
Response Format Validation.Success Retry After Present When Retry Events ✅ 2763ms
Response Format Validation.Success No Retry After When Drop Only ✅ 2752ms
Response Format Validation.Response Echoes Request Id ✅ 2733ms
Retry Behavior.Retries On 408 ✅ 8873ms
Retry Behavior.Retries On 500 ✅ 8862ms
Retry Behavior.Retries On 503 ✅ 11239ms
Retry Behavior.Retries On 504 ✅ 9265ms
Retry Behavior.Retries On 404 ✅ 5299ms
Retry Behavior.Retries On 429 ✅ 8698ms
Retry Behavior.Retries On 502 ✅ 8802ms
Retry Behavior.Retryable Errors Have Retry After ✅ 6190ms
Retry Behavior.Respects Retry After On Retryable Error ✅ 10780ms
Retry Behavior.Does Not Retry On 400 ✅ 2346ms
Retry Behavior.Does Not Retry On 401 ✅ 4749ms
Retry Behavior.Does Not Retry On 402 ✅ 4798ms
Retry Behavior.Does Not Retry On 413 ✅ 4784ms
Retry Behavior.Does Not Retry On 415 ✅ 2418ms
Retry Behavior.Non Retryable Errors Have No Retry After ✅ 4750ms
Retry Behavior.Implements Backoff ✅ 17723ms
Partial Batch Handling.Handles 200 Full Success ✅ 4757ms
Partial Batch Handling.Handles 200 With All Ok ✅ 5758ms
Partial Batch Handling.Does Not Retry Dropped Events ✅ 5712ms
Partial Batch Handling.Does Not Retry Warning Events ✅ 5742ms
Partial Batch Handling.Prunes Ok Events On Partial Retry ✅ 7917ms
Partial Batch Handling.Prunes Dropped Events On Partial Retry ✅ 7748ms
Partial Batch Handling.Retries Only Retry Events From Partial ✅ 7807ms
Partial Batch Handling.Partial Retry Preserves Uuids ✅ 7653ms
Partial Batch Handling.Partial Retry Attempt Header Increments ✅ 7840ms
Partial Batch Handling.Partial Retry Request Id Preserved ✅ 7705ms
Partial Batch Handling.Respects Retry After On Partial ✅ 8032ms
Partial Batch Handling.Unknown Result Treated As Terminal ✅ 5820ms
Partial Batch Handling.Mixed Ok Drop Warning No Retry ✅ 5708ms
Compression.Sends Gzip Content Encoding ✅ 2800ms
Compression.No Content Encoding When Disabled ✅ 2698ms
Compression.Compressed Body Is Decompressible ✅ 2754ms
Error Handling.Does Not Retry On Unknown 4Xx ✅ 4683ms
Event Options.Cookieless Mode Override ✅ 2764ms
Event Options.Disable Skew Correction Override ✅ 2776ms
Event Options.Process Person Profile Override ✅ 2688ms
Event Options.Product Tour Id Override ✅ 2766ms
Event Options.Unset Options Omitted ✅ 2791ms
Event Options.Options Override In Batch ✅ 435ms
Event Options.Unknown Option Passes Through ✅ 2647ms
Event Options.Option Value Is Not Converted ✅ 2751ms
Event Options.Lenient Bool Option Values Are Not Converted ✅ 401ms
Event Options.Option Wins Over Legacy Property ✅ 2722ms
Event Options.Legacy Property Fills Unset Option ✅ 2744ms
Event Options.Null Option Falls Back To Legacy Property ✅ 2633ms
Property Layers.Caller Property Beats Registered Property ✅ 286ms
Property Layers.Before Send Runs Last ✅ 300ms
Fail Open.Empty Api Key Sends Nothing ✅ 1293ms
Fail Open.Personal Api Key Sends Nothing ✅ 1193ms
Geoip And Historical Migration.Geoip Disable Injected Into Properties ✅ 2769ms
Geoip And Historical Migration.Historical Migration Absent By Default ✅ 2688ms

Capture_Ai_V1 Tests

✅ 111/111 tests passed

View Details
Test Status Duration
Endpoint And Method.Targets V1 Endpoint ✅ 2700ms
Endpoint And Method.Does Not Use Legacy Endpoints ✅ 2779ms
Endpoint And Method.Capture Does Not Reroute Ai Named Events ✅ 2755ms
Endpoint And Method.Capture Ai Does Not Reroute Non Ai Events ✅ 2795ms
Lane Isolation.Failing Ai Lane Does Not Delay Analytics ✅ 11224ms
Required Headers.Has Authorization Bearer Header ✅ 2793ms
Required Headers.Has Content Type Json ✅ 2678ms
Required Headers.Has Posthog Sdk Info Format ✅ 284ms
Required Headers.Has Posthog Attempt Header ✅ 2738ms
Required Headers.Has Posthog Request Id ✅ 2801ms
Required Headers.Has Posthog Request Timestamp ✅ 366ms
Required Headers.Has User Agent ✅ 2657ms
Body Format.Body Has Created At And Batch ✅ 2620ms
Body Format.No Api Key In Body ✅ 2788ms
Body Format.No Sent At In Body ✅ 2764ms
Event Format.Event Has Required Root Fields ✅ 2702ms
Event Format.Event Uuid Is Valid ✅ 2771ms
Event Format.Event Timestamp Is Rfc3339 ✅ 2765ms
Event Format.Non Utc Event Timestamp Is Converted To Utc ✅ 237ms
Event Format.Distinct Id Is String ✅ 2765ms
Event Format.Distinct Id At Root Not Properties ✅ 2775ms
Event Format.Custom Properties Preserved ✅ 2657ms
Event Format.Set Properties Preserved ✅ 2802ms
Event Format.Set Once Properties Preserved ✅ 2777ms
Event Format.Groups Properties Preserved ✅ 327ms
Event Format.Sdk Generates Uuid If Not Provided ✅ 2678ms
Event Format.Event Has Required Root Fields Batch ✅ 2781ms
Event Format.Event Uuid Is Valid Batch ✅ 2733ms
Event Format.Event Timestamp Is Rfc3339 Batch ✅ 382ms
Event Format.Distinct Id Is String Batch ✅ 2719ms
Event Format.Distinct Id At Root Not Properties Batch ✅ 2715ms
Event Format.Custom Properties Preserved Batch ✅ 2763ms
Event Format.Set Properties Preserved Batch ✅ 2828ms
Event Format.Set Once Properties Preserved Batch ✅ 2794ms
Event Format.Groups Properties Preserved Batch ✅ 2804ms
Event Format.Sdk Generates Uuid If Not Provided Batch ✅ 2801ms
Batch Behavior.Multiple Events In Single Batch ✅ 2810ms
Batch Behavior.Batch Envelope Smoke ✅ 2816ms
Batch Behavior.Flush At Triggers Batch ✅ 1191ms
Batch Behavior.Created At Reflects Batch Creation Time ✅ 2657ms
Deduplication.Generates Unique Uuids ✅ 2829ms
Deduplication.Different Events Same Content Different Uuids ✅ 2857ms
Deduplication.Preserves Uuid On Retry ✅ 9208ms
Deduplication.Preserves Timestamp On Retry ✅ 9239ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7773ms
Deduplication.No Duplicate Events In Batch ✅ 2879ms
Header Behavior On Retry.Attempt Header Starts At One ✅ 2715ms
Header Behavior On Retry.Attempt Header Increments On Retry ✅ 15790ms
Header Behavior On Retry.Request Id Preserved On Retry ✅ 8768ms
Header Behavior On Retry.Different Requests Have Different Request Ids ✅ 4982ms
Header Behavior On Retry.Request Timestamp Changes On Retry ✅ 5363ms
Response Format Validation.Success Response Has Uuid Keyed Results ✅ 2816ms
Response Format Validation.Success Response Has Ok For Each Event ✅ 2774ms
Response Format Validation.Success No Retry After When All Ok ✅ 2778ms
Response Format Validation.Success Retry After Present When Retry Events ✅ 2745ms
Response Format Validation.Success No Retry After When Drop Only ✅ 2802ms
Response Format Validation.Response Echoes Request Id ✅ 2704ms
Retry Behavior.Retries On 408 ✅ 9312ms
Retry Behavior.Retries On 500 ✅ 9257ms
Retry Behavior.Retries On 503 ✅ 11187ms
Retry Behavior.Retries On 504 ✅ 9105ms
Retry Behavior.Retries On 404 ✅ 8770ms
Retry Behavior.Retries On 429 ✅ 9123ms
Retry Behavior.Retries On 502 ✅ 8717ms
Retry Behavior.Retryable Errors Have Retry After ✅ 5790ms
Retry Behavior.Respects Retry After On Retryable Error ✅ 10748ms
Retry Behavior.Does Not Retry On 400 ✅ 4745ms
Retry Behavior.Does Not Retry On 401 ✅ 4749ms
Retry Behavior.Does Not Retry On 402 ✅ 4793ms
Retry Behavior.Does Not Retry On 413 ✅ 4735ms
Retry Behavior.Does Not Retry On 415 ✅ 4829ms
Retry Behavior.Non Retryable Errors Have No Retry After ✅ 4762ms
Retry Behavior.Implements Backoff ✅ 18247ms
Partial Batch Handling.Handles 200 Full Success ✅ 2362ms
Partial Batch Handling.Handles 200 With All Ok ✅ 5823ms
Partial Batch Handling.Does Not Retry Dropped Events ✅ 5748ms
Partial Batch Handling.Does Not Retry Warning Events ✅ 5770ms
Partial Batch Handling.Prunes Ok Events On Partial Retry ✅ 7806ms
Partial Batch Handling.Prunes Dropped Events On Partial Retry ✅ 7862ms
Partial Batch Handling.Retries Only Retry Events From Partial ✅ 7840ms
Partial Batch Handling.Partial Retry Preserves Uuids ✅ 8036ms
Partial Batch Handling.Partial Retry Attempt Header Increments ✅ 7995ms
Partial Batch Handling.Partial Retry Request Id Preserved ✅ 8111ms
Partial Batch Handling.Respects Retry After On Partial ✅ 7764ms
Partial Batch Handling.Unknown Result Treated As Terminal ✅ 5840ms
Partial Batch Handling.Mixed Ok Drop Warning No Retry ✅ 5886ms
Compression.Sends Gzip Content Encoding ✅ 2931ms
Compression.No Content Encoding When Disabled ✅ 2873ms
Compression.Compressed Body Is Decompressible ✅ 3026ms
Error Handling.Does Not Retry On Unknown 4Xx ✅ 2467ms
Event Options.Cookieless Mode Override ✅ 2908ms
Event Options.Disable Skew Correction Override ✅ 2872ms
Event Options.Process Person Profile Override ✅ 2890ms
Event Options.Product Tour Id Override ✅ 2857ms
Event Options.Unset Options Omitted ✅ 2904ms
Event Options.Options Override In Batch ✅ 541ms
Event Options.Unknown Option Passes Through ✅ 2804ms
Event Options.Option Value Is Not Converted ✅ 2887ms
Event Options.Lenient Bool Option Values Are Not Converted ✅ 2870ms
Event Options.Option Wins Over Legacy Property ✅ 2812ms
Event Options.Legacy Property Fills Unset Option ✅ 2875ms
Event Options.Null Option Falls Back To Legacy Property ✅ 505ms
Event Size.Event Over Ceiling Is Not Sent ✅ 7106ms
Event Size.Over Ceiling Drop Is Reported Or Logged Without Content ✅ 2728ms
Event Size.Batches Close Before Byte Target ✅ 8261ms
Geoip And Historical Migration.Geoip Disable Injected Into Properties ✅ 2844ms
Geoip And Historical Migration.Historical Migration Absent By Default ✅ 2721ms
Property Layers.Caller Property Beats Registered Property ✅ 317ms
Property Layers.Before Send Runs Last ✅ 2782ms
Fail Open.Empty Api Key Sends Nothing ✅ 1358ms
Fail Open.Personal Api Key Sends Nothing ✅ 1228ms

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 2793ms
Request Payload.Flags Request Uses V2 Query Param ✅ 2820ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 2780ms
Request Payload.Flags Request Omits Authorization Header ✅ 2687ms
Request Payload.Token In Flags Body Matches Init ✅ 2678ms
Request Payload.Groups Round Trip ✅ 2756ms
Request Payload.Groups Default To Empty Object ✅ 2907ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 2825ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 2690ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 2811ms
Request Lifecycle.No Flags Request On Init Alone ✅ 68ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 2804ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 5492ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 2827ms
Retry Behavior.Retries Flags On 502 ✅ 2834ms
Retry Behavior.Retries Flags On 504 ✅ 2943ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 3134ms

@veria-ai

veria-ai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

PR overview

No security issues were found in this pull request.

Reviews

@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 51fa0ac: 1 Should fix.

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/Utils/DictUtils.swift Resolved
A dictionary with number or boolean keys, such as one added in beforeSend,
skipped the null cleanup and was then stringified by sanitizeDictionary,
so its null members reached the queue as JSON null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@turnipdabeets
turnipdabeets merged commit 8395863 into chore/v4-remove-deprecated Nov 9, 2026
53 checks passed
@turnipdabeets
turnipdabeets deleted the fix/v4-drop-null-properties branch November 9, 2026 20:47
@turnipdabeets turnipdabeets mentioned this pull request Nov 9, 2026
6 of 18 tasks
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