Skip to content
Latchkey

GitHub Actions contains() Always False - Wrong Argument Type

A contains() check never matches because the first argument is the wrong type - a JSON string instead of a real array, or a value whose format or case differs from what you compare against.

What this error means

A step gated by contains() is always skipped (or always runs) regardless of the actual data. The expression is valid, but the membership test never returns the result you expect.

.github/workflows/ci.yml
# matrix value is a JSON string, not an array, so this never matches as intended
if: ${{ contains('["a","b"]', matrix.flavor) }}

Common causes

String passed where an array is expected

contains(array, item) checks membership in an array, while contains(string, substring) does substring matching. Passing a JSON-looking string runs the substring form, which rarely matches what you meant.

Case or format mismatch

contains() is case-sensitive. Comparing github.event.action or a label whose case or format differs from your literal silently fails to match.

How to fix it

Use a real array with fromJSON or a list

.github/workflows/ci.yml
if: ${{ contains(fromJSON('["a","b"]'), matrix.flavor) }}
# or build a real array elsewhere and reference it

Match the value exactly

  1. Echo the value first to confirm its exact text and case.
  2. For substring checks, ensure both operands are strings and the case matches.
  3. For membership, pass a genuine array (fromJSON or a context array), not a string.

How to prevent it

  • Be explicit about whether you want substring or array membership.
  • Use fromJSON to turn a JSON string into a real array before contains().
  • Echo context values once to confirm their exact format and case.

Related guides

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