Skip to content
Latchkey

GitHub Actions contains() returns unexpected results from a type mismatch in an if

contains(search, item) works on strings and arrays, and GitHub Actions coerces operands. A number compared against a string, or a scalar passed where an array is expected, can make contains() return a surprising true or false in an if.

What this error means

An if using contains() never matches (or always matches) even though the value clearly should compare equal.

github-actions
# matrix.node is a number; the array holds numbers, but a quoted compare fails
if: contains('18 20 22', matrix.node)   # number coerced into a substring search

Common causes

Number vs string coercion

contains() on a string does a substring match after coercing the item to a string; numeric edges (e.g. 2 inside 22) match unexpectedly.

Scalar passed where an array is intended

Passing a scalar instead of an array changes contains() from membership to substring semantics.

How to fix it

Compare against an explicit array

  1. Build a real array with fromJSON and use array-membership semantics.
  2. This avoids substring false positives from numeric coercion.
.github/workflows/ci.yml
if: ${{ contains(fromJSON('[18,20,22]'), matrix.node) }}

Normalize both operands to strings deliberately

  1. When you do want substring matching, quote and delimit values so partial numbers cannot match.
  2. Wrap each token, e.g. compare against ’,18,20,22,’ with surrounding commas.

How to prevent it

  • Use fromJSON arrays for membership checks rather than space-delimited strings.
  • Be explicit about whether you want substring or membership semantics.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →