nektos/act · error
the workflow is not valid. Matrix exclude key %q does not ma
Error message
the workflow is not valid. Matrix exclude key %q does not match any key within the matrix
What it means
During matrix expansion, act verifies every key used in a `matrix.exclude` entry exists as a top-level matrix key. GitHub fails hard on exclude entries referencing undefined matrix keys (but silently skips non-matching include entries), and act replicates that behavior by returning this error.
Source
Thrown at pkg/model/workflow.go:432
i := i.(map[string]interface{})
includes = append(includes, i)
}
case interface{}:
v := v.(map[string]interface{})
includes = append(includes, v)
}
}
delete(m, "include")
excludes := make([]map[string]interface{}, 0)
for _, e := range m["exclude"] {
e := e.(map[string]interface{})
for k := range e {
if _, ok := m[k]; ok {
excludes = append(excludes, e)
} else {
// We fail completely here because that's what GitHub does for non-existing matrix keys, fail on exclude, silent skip on include
return nil, fmt.Errorf("the workflow is not valid. Matrix exclude key %q does not match any key within the matrix", k)
}
}
}
delete(m, "exclude")
matrixProduct := common.CartesianProduct(m)
MATRIX:
for _, matrix := range matrixProduct {
for _, exclude := range excludes {
if commonKeysMatch(matrix, exclude) {
log.Debugf("Skipping matrix '%v' due to exclude '%v'", matrix, exclude)
continue MATRIX
}
}
matrixes = append(matrixes, matrix)
}
for _, include := range includes {
matched := falseView on GitHub (pinned to 4f41128141)
Solutions
- Align every key in each exclude entry with the matrix's top-level dimensions.
- Fix typos in exclude key names to match matrix keys exactly (case-sensitive).
- For value-based exclusions, ensure the value belongs to the defined matrix array — the key must exist even if the value combination never occurs (GitHub then simply skips it).
Example fix
# before
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20]
exclude:
- os: macos-latest
env: prod # 'env' is not a matrix key
# after
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20]
exclude:
- os: macos-latest
node: 18 Defensive patterns
Strategy: validation
Validate before calling
func validateExcludeKeys(matrix map[string]interface{}) error {
for _, e := range toSlice(matrix["exclude"]) {
m, ok := e.(map[string]interface{})
if !ok { continue }
for k := range m {
if _, ok := matrix[k]; !ok {
return fmt.Errorf("exclude key %q not in matrix", k)
}
}
}
return nil
} Prevention
- Every key in an exclude entry must be a top-level matrix dimension — no extras.
- Rename matrix dimensions and exclude keys together in one commit.
- Copy-paste exclude blocks only after checking the source matrix keys.
When it happens
Trigger: A matrix defines os: [ubuntu-latest] and node: [20], but an exclude entry uses `{ os: windows-latest, foo: bar }` — key `foo` is not a matrix key, so expansion aborts. Also triggered by typos in exclude keys (`noded` instead of `node`).
Common situations: Copying exclude blocks from another workflow whose matrix has different keys; renaming a matrix dimension without updating excludes; excluding on a value that was moved into an include-generated dimension.
Related errors
- workflow is not valid. '%s': %w
- workflow is not valid. '%s': Job name '%s' is invalid. Names
- Actions YAML Schema Validation Error detected:\nFor more inf
- Actions YAML Strict Schema Validation Error detected:\nFor m
- `uses` key references invalid workflow path '%s'. Must start
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/b8f9bde024cc0dee.
Report an issue: GitHub.