Skip to content

Equal.equals crashes with null inside structuralRegion #6132

@aniravi24

Description

@aniravi24

Bug Report

Equal.equals throws TypeError: Cannot convert undefined or null to object when comparing values where one is null and the other is a non-null object, inside a structuralRegion.

Reproduction

import * as Equal from "effect/Equal"
import * as Utils from "effect/Utils"

// This crashes:
Utils.structuralRegion(() => Equal.equals({ name: "hello" }, null))
// TypeError: Cannot convert undefined or null to object
//   at Object.getPrototypeOf (<anonymous>)
//   at compareBoth (Equal.ts)

Root Cause

In compareBoth, when selfType === "object":

  1. Line checking self !== null && that !== null correctly prevents entering the first block when one is null
  2. But it falls through to the structuralRegionState.enabled block
  3. Object.getPrototypeOf(self) is called without a null guard — crashes when self is null

This is because typeof null === "object" in JavaScript, so null passes the type check but then Object.getPrototypeOf(null) throws.

Suggested Fix

Add a null guard before the getPrototypeOf calls:

if (structuralRegionState.enabled) {
  if (self === null || that === null) {
    return false;
  }
  // ... rest of structural comparison
}

Environment

  • effect@3.20.0
  • Discovered when using structural equality comparison on form state objects containing nullable fields

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions