{"id":"fcaef83c3d55b7f8","repo":"jestjs/jest","slug":"expected-is-not-a-string-or-a-regexp","errorCode":null,"errorMessage":"Expected is not a String or a RegExp","messagePattern":"Expected is not a String or a RegExp","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/expect/src/asymmetricMatchers.ts","lineNumber":326,"sourceCode":"  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}\n\nclass StringMatching extends AsymmetricMatcher<RegExp> {\n  constructor(sample: string | RegExp, inverse = false) {\n    if (!isA('String', sample) && !isA('RegExp', sample)) {\n      throw new Error('Expected is not a String or a RegExp');\n    }\n    super(new RegExp(sample), inverse);\n  }\n\n  asymmetricMatch(other: unknown) {\n    const result = isA<string>('String', other) && this.sample.test(other);\n\n    return this.inverse ? !result : result;\n  }\n\n  toString() {\n    return `String${this.inverse ? 'Not' : ''}Matching`;\n  }\n\n  override getExpectedType() {\n    return 'string';\n  }\n}","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/expect/src/asymmetricMatchers.ts#L308-L344","documentation":"StringMatching's constructor accepts either a String or a RegExp (it will wrap a string sample with new RegExp(sample)); any other type throws. This makes stringMatching the flexible matcher (substring-as-regex or real regex), complementing stringContaining which is strictly substring.","triggerScenarios":"Calling expect.stringMatching(123), expect.stringMatching(null), expect.stringMatching({}), or expect.stringMatching(undefined).","commonSituations":"Passing a number expecting implicit coercion; passing an object by mistake; a variable that was supposed to hold a regex/string but is undefined.","solutions":["Pass a regex: expect.stringMatching(/^foo/), or a string that is a valid regex pattern: expect.stringMatching('foo').","Ensure the value is defined and is a string or RegExp before constructing the matcher.","Use expect.stringContaining if you want a literal substring with no regex semantics."],"exampleFix":"// before\nexpect(msg).toEqual(expect.stringMatching(404));\n\n// after\nexpect(msg).toEqual(expect.stringMatching(/404/));\n// or\nexpect(msg).toEqual(expect.stringContaining('404'));","handlingStrategy":"type-guard","validationCode":"if (typeof sample !== 'string' && !(sample instanceof RegExp) && !(sample instanceof String)) {\n  throw new TypeError('expect.stringMatching needs a string or RegExp');\n}\nexpect.stringMatching(sample);","typeGuard":"function isStringOrRegExp(x: unknown): x is string | RegExp {\n  return typeof x === 'string' || x instanceof RegExp || x instanceof String;\n}","tryCatchPattern":"// constructor throws synchronously — validate the sample before calling","preventionTips":["Remember stringMatching interprets strings as regex patterns.","Use stringContaining for literal substrings without regex semantics.","Confirm the variable holds a regex/string and is defined."],"tags":["expect","asymmetric-matcher","string","regex","validation"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}