Skip to content

Reproduce RUMS-5828: 128 attribute cap drops legitimate payloads#1274

Draft
mariusc83 wants to merge 1 commit intodevelopfrom
mconstantin/RUMS-5828/attr-limit-128-drops-logs
Draft

Reproduce RUMS-5828: 128 attribute cap drops legitimate payloads#1274
mariusc83 wants to merge 1 commit intodevelopfrom
mconstantin/RUMS-5828/attr-limit-128-drops-logs

Conversation

@mariusc83
Copy link
Copy Markdown
Member

Reproduction for RUMS-5828

Issue Summary

The React Native SDK's v3 attribute encoder caps every event at 128 leaf attributes via MAX_ATTRIBUTES = 128 in packages/core/src/sdk/AttributesEncoding/helpers.ts, silently dropping any leaves beyond the cap. Realistic payloads with arrays of small objects (e.g. 22 items × 6 props = 132 leaves) trigger the cap during normal DdLogs.info(...) usage. In the nested-array case the overflow happens before the array wrapper itself is written, so the entire top-level attribute is dropped — the customer's payload reaches the native layer as {}.

Reproduction Tests

  • Unit tests: 7 (in packages/core/src/sdk/AttributesEncoding/__tests__/attributesEncoding.test.ts)
  • Integration tests: 0

What the Tests Prove

Three new tests in the RUMS-5828: 128 attribute cap drops legitimate payloads describe block fail today, documenting the bug as the customer experiences it:

  1. A nested-array payload of 132 leaves (22 × 6-prop objects) yields an empty result instead of preserving all 22 items × 6 props.
  2. A flat 129-key input is capped at 128 instead of being preserved.
  3. Internal _dd.* attributes consume slots in the user-attribute budget instead of being SDK overhead.

Four companion tests under RUMS-5828: current behavior pin (regression contract) describe the exact present-day semantics; they pass today and serve as a regression contract against accidental future changes:

  • The 132-leaf customer payload yields an empty {} plus 1 limit-reached warn + 5 dropped-attribute warns (4 inner-prop drops on the 22nd item: 'c', 'd', 'e', 'f', plus 1 wrapper drop for 'basicTestArray').
  • A flat 128-key input passes unchanged with no warnings.
  • A flat 129-key input is capped at 128 with one limit warn and one drop warn for 'k128'.
  • _dd.* attributes consume one slot of the 128-attribute budget.

Root Cause Analysis

The v3 attribute-encoding rewrite (introduced in #1008, commit a3c778c) added a hard cap of 128 in addEncodedAttribute. The cap was chosen as a defensive halving of the documented 256-attribute platform limit because validateAttributes is called twice per event-path. With recursive flattening (arrays of objects expanded as nested objects whose primitive properties each call addEncodedAttribute and increment numOfAttributes), legitimate analytics payloads can exceed 128 leaves and trigger silent drops. In the nested-array case, the inner-leaf increments overflow the cap before the outer array wrapper is written, so even the top-level attribute itself is dropped.

Call Chain

DdLogs.info(message, context)DdLogsWrapper.log(...)encodeAttributes(event.context)encodeAttributesInPlace(value, out, path, encoders, context) (recurses into arrays/objects) → for each item in the array, normalize(item) → recursive encodeAttributesInPlace(item, nested, [], encoders, context)addEncodedAttribute(nested, [k], v, context) per leaf → if context.numOfAttributes >= 128: emit warns and drop. After all items processed, the outer-array addEncodedAttribute(out, ['basicTestArray'], normalizedArray, context) is also dropped because numOfAttributes is now at the cap.

Regression Evidence

On source:react-native, v3.3.0 (released ~mid-April 2026, ~3.9M sessions over 30d) introduced the JS-side attribute encoder cap of 128 leaves per event in commit a3c778c (PR #1008, Limit encoded attributes to 128). The platform's documented per-event limit is 256 attributes (with backend feature-flag rum_parse_big_events extending to 2048). The RN cap is intentionally conservative versus the backend ceiling. No new failure mode in logs.rum.telemetry.errors for v3.3.0 vs v3.2.0 or v2.14.3 — the attribute-drop is reported only as a JS console.warn and is not measurable in the public-side telemetry metric family.

Failure Output

encodeAttributes
  RUMS-5828: 128 attribute cap drops legitimate payloads
    ✕ preserves all 132 leaves of the customer-reported nested-array payload
        expect(received).toBeDefined()
        Received: undefined
        > 553 |             expect(result.basicTestArray).toBeDefined();
    ✕ preserves a flat 129-key input without dropping any attribute
        expect(received).toHaveLength(expected)
        Expected length: 129
        Received length: 128
        > 588 |             expect(Object.keys(result)).toHaveLength(129);
    ✕ does not let internal _dd.* attributes consume the user-attribute budget
        expect(received).toBe(expected) // Object.is equality
        Expected: 127
        Received: undefined
        > 614 |                 expect(result[`k${i}`]).toBe(i);

Generated by rum:tee-triage-insights

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.

1 participant