vitest-dev/vitest · error · Error
Expected is not a string
Error message
Expected is not a string
What it means
Thrown by the StringContaining asymmetric matcher constructor when the sample is not a string (checked via Object.prototype.toString). StringContaining tests substring inclusion, so a non-string expected value is invalid at construction time.
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 d568f8ce37)
Solutions
- Ensure the argument to expect.stringContaining is a string.
- Coerce or stringify the value if substring semantics are intended.
- For numeric/object checks, use the appropriate matcher (objectContaining, arrayContaining).
Example fix
// before
expect(obj).toEqual({ code: expect.stringContaining(404) })
// after
expect(obj).toEqual({ code: expect.stringContaining('NF') }) Defensive patterns
Strategy: type-guard
Validate before calling
function asString(v: unknown): string {
if (typeof v !== 'string') throw new TypeError(`stringContaining needs a string, got ${typeof v}`)
return v
}
expect(obj).toEqual({ msg: expect.stringContaining(asString(sub)) }) Type guard
function isString(v: unknown): v is string {
return typeof v === 'string'
} Prevention
- Type variables passed to stringContaining as string.
- Add a unit test asserting the sample is a string in shared assertion helpers.
- Avoid using any-typed values as matcher samples.
When it happens
Trigger: Constructing expect.stringContaining(value) where value is a number, object, null, etc. The isA('String', sample) guard fails and the constructor throws before any match.
Common situations: Passing a non-string by mistake (e.g. expect.stringContaining(123) or a variable typed as any that holds a number); refactoring where the expected value type changed.
Related errors
- You must provide an object to ${this.toString()}, not '${typ
- You must provide an array to ${this.toString()}, not '${type
- any() expects to be passed a constructor function. Please pa
- Expected is not a String or a RegExp
- Expected is not a Number
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/ac82d9967a25e533.json.
Report an issue: GitHub.