vitest-dev/vitest · error · Error
Expected is not a string
Error message
Expected is not a string
What it means
The StringContaining asymmetric matcher (expect.stringContaining) requires its sample to be a string; isA('String', sample) returns false for any non-string and the constructor throws. This is a fail-fast construction-time check, not a match-time one.
Solutions
- Pass a plain string substring to expect.stringContaining.
- If you need pattern matching, use expect.stringMatching(regexOrString).
- Coerce or validate the value is a string before passing: String(sample) or a type guard.
Example fix
// before
expect(result).toEqual(expect.stringContaining(404))
// after
expect(result).toEqual(expect.stringContaining('Not Found')) Defensive patterns
Strategy: type-guard
Validate before calling
function asStringContaining(sample) {
if (typeof sample !== 'string') {
throw new TypeError('expect.stringContaining needs a string')
}
return expect.stringContaining(sample)
} Type guard
function isString(v): v is string {
return typeof v === 'string'
} Prevention
- Use expect.stringContaining only with string literals.
- Reach for expect.stringMatching when a RegExp is needed.
- Add a typeof check when the value comes from untyped config.
When it happens
Trigger: expect.stringContaining(sample) called with sample that is a number, object, null, etc.
Common situations: Passing a variable whose type is not narrowed (e.g. a config value typed as string | number); passing a RegExp where a substring was expected (use stringMatching instead).
Related errors
- any() expects to be passed a constructor function. Please…
- Expected is not a Number
- Expected is not a String or a RegExp
- Precision is not a Number
- You must provide an array to
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/ac82d9967a25e533.
Report an issue: GitHub.
Appendix: source
Thrown at packages/expect/src/jest-asymmetric-matchers.ts:77
}
// implement custom chai/loupe inspect for better AssertionError.message formatting
// https://github.com/chaijs/loupe/blob/9b8a6deabcd50adc056a64fb705896194710c5c6/src/index.ts#L29
// @ts-expect-error computed properties is not supported when isolatedDeclarations is enabled
// FIXME: https://github.com/microsoft/TypeScript/issues/61068
AsymmetricMatcher.prototype[Symbol.for('chai/inspect')] = function (options: { depth: number; truncate: number }): string {
// minimal pretty-format with simple manual truncation
const result = stringify(this, options.depth, { min: true })
if (result.length <= options.truncate) {
return result
}
return `${this.toString()}{…}`
}
export class StringContaining extends AsymmetricMatcher<string> {
constructor(sample: string, inverse = false) {
if (!isA('String', sample)) {
throw new Error('Expected is not a string')
}
super(sample, inverse)
}
asymmetricMatch(other: string): boolean {
const result = isA('String', other) && other.includes(this.sample)
return this.inverse ? !result : result
}
toString() {
return `String${this.inverse ? 'Not' : ''}Containing`
}
getExpectedType() {
return 'string'
}View on GitHub (pinned to 1fa9837ec2)