{"id":"2ac37afb6a23af58","repo":"jestjs/jest","slug":"expected-is-not-a-string","errorCode":null,"errorMessage":"Expected is not a string","messagePattern":"Expected is not a string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/expect/src/asymmetricMatchers.ts","lineNumber":303,"sourceCode":"      }\n    }\n\n    return this.inverse ? !result : result;\n  }\n\n  toString() {\n    return `Object${this.inverse ? 'Not' : ''}Containing`;\n  }\n\n  override getExpectedType() {\n    return 'object';\n  }\n}\n\nclass StringContaining extends AsymmetricMatcher<string> {\n  constructor(sample: string, inverse = false) {\n    if (!isA('String', sample)) {\n      throw new Error('Expected is not a string');\n    }\n    super(sample, inverse);\n  }\n\n  asymmetricMatch(other: unknown) {\n    const result = isA<string>('String', other) && other.includes(this.sample);\n\n    return this.inverse ? !result : result;\n  }\n\n  toString() {\n    return `String${this.inverse ? 'Not' : ''}Containing`;\n  }\n\n  override getExpectedType() {\n    return 'string';\n  }\n}","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/expect/src/asymmetricMatchers.ts#L285-L321","documentation":"StringContaining's constructor validates the sample with isA('String', sample), accepting both primitives and boxed String objects. Anything else (number, regex, object) throws immediately at construction. expect.stringContaining is meant to assert a substring is present in a received string.","triggerScenarios":"Calling expect.stringContaining(123), expect.stringContaining(/re/) (use stringMatching instead), expect.stringContaining(undefined), or expect.stringContaining(someObject).","commonSituations":"Passing a RegExp where a substring was intended; passing a variable whose value is not a string; mixing up stringContaining and stringMatching.","solutions":["Pass a string substring: expect.stringContaining('hello').","For regex matching use expect.stringMatching(/pattern/).","Coerce when appropriate: expect.stringContaining(String(val))."],"exampleFix":"// before\nexpect(name).toEqual(expect.stringContaining(/J.*/i));\n\n// after — use stringMatching for regex\nexpect(name).toEqual(expect.stringMatching(/^J/i));\n// or pass a literal substring\nexpect(name).toEqual(expect.stringContaining('J'));","handlingStrategy":"type-guard","validationCode":"if (typeof sample !== 'string' && !(sample instanceof String)) {\n  throw new TypeError('expect.stringContaining needs a string');\n}\nexpect.stringContaining(sample);","typeGuard":"function isStringLike(x: unknown): x is string | String {\n  return typeof x === 'string' || x instanceof String;\n}","tryCatchPattern":"// constructor throws synchronously — validate the sample before calling","preventionTips":["Use stringContaining only for literal substrings.","For regex use stringMatching; for objects use objectContaining.","Coerce validated values: String(val)."],"tags":["expect","asymmetric-matcher","string","validation"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}