Skip to content

TypeError: Cannot read properties of null (reading 'reduce') when using getTreatmentsWithConfig with rule-based segments (proxy 5.11.0+) #939

Description

@etremblay

Description

Upgrading the Split Proxy from 5.10.3 to 5.11.0+ (tested up to 5.12.7) causes an unhandled TypeError crash when getTreatmentsWithConfig is called and one or more feature flags use rule-based segments.

The error is thrown synchronously during SDK evaluation on SDK_READY, crashing the evaluation of all treatments in the batch.

Error

Uncaught TypeError: Cannot read properties of null (reading 'reduce')
    at getTreatment
    at eo
    at to (forEach)
    at Qr
    at getTreatmentsWithConfig
    at getTreatmentsWithConfig
    at onReady

Versions

Package Version
@splitsoftware/splitio 11.11.2
@splitsoftware/splitio-redux 2.3.0
Split Proxy (working) 5.10.3
Split Proxy (broken) 5.11.05.12.7

Steps to Reproduce

  1. Configure the JS SDK (11.11.2) to point at a Split Proxy.
  2. Create a feature flag that uses a rule-based segment (introduced in proxy 5.11.0).
  3. Upgrade the proxy from 5.10.3 to 5.11.0 or later.
  4. On SDK ready, call getTreatmentsWithConfig([...]) with a flag that uses a rule-based segment.
  5. Observe the TypeError crash.

Root Cause Analysis

The crash originates in javascript-commons at src/evaluator/matchers/rbsegment.ts.

The IRBSegment DTO type explicitly allows null for several nested fields:

// src/dtos/types.ts
export interface IRBSegment extends TargetingEntity {
  excluded?: {
    keys?: string[] | null,
    segments?: IExcludedSegment[] | null
  } | null
}

Proxy 5.11.0 introduced rule-based segments and may return null values for excluded, excluded.keys, or excluded.segments in the segment payload. The evaluator guards with || [] / || {} which handles undefined but the crash surfaces deeper in the condition evaluation pipeline — inside the parser called from matchConditions — where a matcher data array arrives as null and .reduce() is called on it without a null guard.

// rbsegment.ts – isExcluded
const excluded = rbSegment.excluded || {};          // guards undefined/null ✅
return (excluded.segments || []).reduce(...)        // guards undefined/null ✅

// BUT inside matchConditions → parser → condition matchers:
// a matcher data property (e.g. whitelistMatcherData.whitelist) 
// can arrive as null from the proxy, and .reduce() is called without a null guard

Expected Behavior

getTreatmentsWithConfig should handle null arrays in rule-based segment condition matcher data gracefully, returning 'control' rather than throwing an uncaught TypeError.

Actual Behavior

An uncaught TypeError: Cannot read properties of null (reading 'reduce') is thrown, crashing the entire getTreatmentsWithConfig call and all downstream treatment evaluations.

Workaround

Pin the Split Proxy to 5.10.3 until a fix is available.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions