Skip to content

fix(Match): handle null/undefined in Match.tag and Match.tagStartsWith#6018

Merged
tim-smart merged 1 commit intoEffect-TS:mainfrom
codewithkenzo:fix/match-tag-nullable-union
Feb 3, 2026
Merged

fix(Match): handle null/undefined in Match.tag and Match.tagStartsWith#6018
tim-smart merged 1 commit intoEffect-TS:mainfrom
codewithkenzo:fix/match-tag-nullable-union

Conversation

@codewithkenzo
Copy link
Contributor

Summary

Fixes #6017

Match.tag and Match.tagStartsWith now correctly handle nullable union types instead of crashing with "Cannot read properties of undefined (reading '_tag')".

Problem

When using Match.tag on a union type that includes null or undefined, the predicate would crash because it accessed _[field] without first checking if _ is nullish:

const value = undefined as ({_tag: "A"} | undefined)
const res = Match.value(value).pipe(
  Match.tag('A', () => 'matched A'),  // crashes!
  Match.when(undefined, () => 'matched undefined'),
  Match.exhaustive
)

Solution

Add _ != null && guard to the predicates in discriminator and discriminatorStartsWith, following the same pattern already used in discriminators (which powers Match.tags).

Changes

  • packages/effect/src/internal/matcher.ts: Add null checks to predicates
  • packages/effect/test/Match.test.ts: Add test cases for nullable unions

Testing

Added 3 test cases:

  • Match.tag with undefined union
  • Match.tag with null union
  • Match.tagStartsWith with undefined union

All 62 Match tests pass.

Add null checks to discriminator and discriminatorStartsWith predicates
to prevent crashes when matching nullable union types.

This follows the same pattern already used in discriminators (Match.tags).

Fixes Effect-TS#6017
@changeset-bot
Copy link

changeset-bot bot commented Feb 2, 2026

🦋 Changeset detected

Latest commit: 971727c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 36 packages
Name Type
effect Patch
@effect/cli Patch
@effect/cluster Patch
@effect/experimental Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/platform Patch
@effect/printer-ansi Patch
@effect/printer Patch
@effect/rpc Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-drizzle Patch
@effect/sql-kysely Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/sql Patch
@effect/typeclass Patch
@effect/vitest Patch
@effect/workflow Patch
@effect/ai Patch
@effect/ai-amazon-bedrock Patch
@effect/ai-anthropic Patch
@effect/ai-google Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codewithkenzo
Copy link
Contributor Author

This follows my comment on #6017. The fix adds the same _ != null && guard that discriminators (used by Match.tags) already has.

Minimal change - just 3 lines modified in the predicates.

@tim-smart tim-smart merged commit e71889f into Effect-TS:main Feb 3, 2026
11 checks passed
@github-project-automation github-project-automation bot moved this from Discussion Ongoing to Done in PR Backlog Feb 3, 2026
@github-actions github-actions bot mentioned this pull request Feb 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Match.tag crashes on union type including null/undefined

2 participants