{"record":{"id":"c19479232b6cc3cd","repo":"mikefarah/yq","slug":"v-cannot-check-contained-in-v","errorCode":null,"errorMessage":"%v cannot check contained in %v","messagePattern":"(.+?) cannot check contained in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/operator_contains.go","lineNumber":97,"sourceCode":"\t\treturn containsObject(lhs, rhs)\n\tcase SequenceNode:\n\t\treturn containsArray(lhs, rhs)\n\tcase ScalarNode:\n\t\tif rhs.Kind != ScalarNode || lhs.Tag != rhs.Tag {\n\t\t\treturn false, nil\n\t\t}\n\t\tif lhs.Tag == \"!!null\" {\n\t\t\treturn rhs.Tag == \"!!null\", nil\n\t\t}\n\t\treturn containsScalars(lhs, rhs)\n\t}\n\n\treturn false, fmt.Errorf(\"%v not yet supported for contains\", lhs.Tag)\n}\n\nfunc containsWithNodes(_ *dataTreeNavigator, _ Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {\n\tif lhs.Kind != rhs.Kind {\n\t\treturn nil, fmt.Errorf(\"%v cannot check contained in %v\", rhs.Tag, lhs.Tag)\n\t}\n\n\tresult, err := contains(lhs, rhs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn createBooleanCandidate(lhs, result), nil\n}\n","sourceCodeStart":79,"sourceCodeEnd":107,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/operator_contains.go#L79-L107","documentation":"`containsWithNodes` requires both sides of the `contains` operator to be the same node Kind (map vs map, seq vs seq, scalar vs scalar). When the LHS and RHS kinds differ it immediately returns this error naming the two tags. Note it compares Kinds, and reports Tags in the message, so e.g. checking a scalar contained in an array at top level triggers it.","triggerScenarios":"Running expressions like `'\"abc\" contains [\"a\"]'`, `'.a contains \"x\"'` where .a is a map but the RHS is a scalar, or `'[] contains {}'` — any `contains` where lhs.Kind != rhs.Kind at the top level of the cross-function.","commonSituations":"Hand-writing a contains filter assuming substring semantics on a non-string, or checking array membership with the LHS/RHS reversed (users often write `item contains array` when yq expects `array contains item`). Also common when a field is sometimes a string and sometimes an array across documents.","solutions":["Check both operand kinds before running contains: use `type` in yq (e.g. `.a | type`) to confirm map/seq/scalar on each side","If checking membership, put the array/map on the LHS: `(.fruits | contains([\"apple\"]))` not `\"apple\" contains .fruits`","For substring checks on a string use `test()`/`match` instead of `contains` when the other side is not a string","Guard heterogeneous documents: `select(type == \"!!seq\") | contains([...])` so only sequence documents are compared"],"exampleFix":"// before: kinds mismatch, error\nyq '\"apple\" contains [\"app\"]'\n// after: array on LHS, matching kinds\nyq '[\"apple\"] contains [\"app\"]'   # or use test for substrings:\nyq '\"apple\" | test(\"app\")'","handlingStrategy":"validation","validationCode":"# ensure both sides have the same type before contains\nyq 'select((.a | type) == ($b | type)) | .a contains $b'\n# or in shell, pre-check:\n# yq '.a | type' file.yml  -> must equal type of RHS","typeGuard":"func sameKind(a, b *yqlib.CandidateNode) bool { return a.Kind == b.Kind }","tryCatchPattern":"// wrap the evaluation and inspect the message\nout, err := eval(expr)\nif err != nil && strings.Contains(err.Error(), \"cannot check contained in\") {\n\t// fall back to test() for string substring checks\n}","preventionTips":["Remember yq semantics: array/map goes on the LHS of contains","Use test() for substring matching on strings, not contains","Guard heterogeneous documents with select(type == \"!!seq\") style filters","Check `type` of both operands in an interactive yq run before scripting"],"tags":["yq","contains-operator","type-mismatch"],"backgroundTag":"operand-type-mismatch","analyzedSha":"8b5af0694bb82b41d4ae180fac9972029066f90a","analyzedAt":"2026-09-05T10:57:22.766Z","contentChangedAt":"2026-09-05T10:57:22.766Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}