sindresorhus/is · error · TypeError
Expected value which is not `${description}`, received value
Error message
Expected value which is not `${description}`, received value of type `${is(value)}`. What it means
Thrown by negative assertions created via `createAssertNot` (source/index.ts:1168) — e.g. `assertNotUndefined`, `assertNotNull`, `assertNotString` — when the value *does* match the forbidden type. The message from `typeErrorMessageNot` names the forbidden description and the actual detected type. This is the assertion working as designed: the value violated the 'must not be X' contract.
Source
Thrown at source/index.ts:1171
type NotAssert = {
undefined: NotAssertion<undefined, UnknownNotPrimitive<undefined>>;
// eslint-disable-next-line @typescript-eslint/no-restricted-types
null: NotAssertion<null, UnknownNotPrimitive<null>>;
// eslint-disable-next-line @typescript-eslint/no-restricted-types
nullOrUndefined: NotAssertion<null | undefined, UnknownNotPrimitive<null | undefined>>;
string: NotAssertion<string, UnknownNotPrimitive<string>>;
boolean: NotAssertion<boolean, UnknownNotPrimitive<boolean>>;
symbol: NotAssertion<symbol, UnknownNotPrimitive<symbol>>;
bigint: NotAssertion<bigint, UnknownNotPrimitive<bigint>>;
// eslint-disable-next-line @typescript-eslint/no-restricted-types
primitive: NotAssertion<Primitive, object>;
};
// Negative assertions are limited to types where the assertion rejects every TypeScript value assignable to the forbidden type. Structural object types such as `Map`, `Set`, `Date`, and `Array` are excluded because TypeScript accepts shape-compatible mocks while the runtime checks use object brands, so `Exclude` would narrow values that can pass the negative assertion.
function createAssertNot<Forbidden, UnknownResult = unknown>(predicate: Predicate, description: AssertionTypeDescription): NotAssertion<Forbidden, UnknownResult> {
return <Value>(value: Value, message?: string): asserts value is NotAssertionResult<Value, Forbidden, UnknownResult> => {
if (predicate(value)) {
throw new TypeError(message ?? typeErrorMessageNot(description, value));
}
};
}
export const assertNotUndefined: NotAssertion<undefined, UnknownNotPrimitive<undefined>> = createAssertNot<undefined, UnknownNotPrimitive<undefined>>(isUndefined, 'undefined');
// eslint-disable-next-line @typescript-eslint/no-restricted-types
export const assertNotNull: NotAssertion<null, UnknownNotPrimitive<null>> = createAssertNot<null, UnknownNotPrimitive<null>>(isNull, 'null');
// eslint-disable-next-line @typescript-eslint/no-restricted-types
export const assertNotNullOrUndefined: NotAssertion<null | undefined, UnknownNotPrimitive<null | undefined>>
// eslint-disable-next-line @typescript-eslint/no-restricted-types
= createAssertNot<null | undefined, UnknownNotPrimitive<null | undefined>>(isNullOrUndefined, 'null or undefined');
export const assertNotString: NotAssertion<string, UnknownNotPrimitive<string>> = createAssertNot<string, UnknownNotPrimitive<string>>(isString, 'string');
export const assertNotBoolean: NotAssertion<boolean, UnknownNotPrimitive<boolean>> = createAssertNot<boolean, UnknownNotPrimitive<boolean>>(isBoolean, 'boolean');
export const assertNotSymbol: NotAssertion<symbol, UnknownNotPrimitive<symbol>> = createAssertNot<symbol, UnknownNotPrimitive<symbol>>(isSymbol, 'symbol');
export const assertNotBigint: NotAssertion<bigint, UnknownNotPrimitive<bigint>> = createAssertNot<bigint, UnknownNotPrimitive<bigint>>(isBigint, 'bigint');
export const assertNotPrimitive: NotAssertion<Primitive, object> = createAssertNot<Primitive, object>(isPrimitive, 'primitive'); // eslint-disable-line @typescript-eslint/no-restricted-types
// We intentionally do not support `assert.not(is.undefined, value)`. TypeScript cannot derive safe complement types from arbitrary predicates, and many predicates here are refinements (for example, `is.number` rejects `NaN`). Explicit methods keep runtime checks and type narrowing aligned.View on GitHub ↗ (pinned to 7821031c66)
Solutions
- Treat this as a data problem, not a library problem: trace why the value is the forbidden type at that point (missing config, absent field, uninitialized state) and fix the source.
- If the forbidden type is legitimately possible, replace the assertion with a conditional branch that handles that case.
- Pass a custom `message` argument to the assertion so failures identify which value and context failed.
Example fix
// before const url = process.env.API_URL; assertNotUndefined(url); // throws when env var unset // after const url = process.env.API_URL; assertNotUndefined(url, 'API_URL environment variable must be set');
Defensive patterns
Strategy: try-catch
Validate before calling
if (is.nan(value)) {
// handle the disallowed type yourself before calling assert.not.*
} Type guard
function isNot<T>(predicate: (v: unknown) => boolean, value: unknown): boolean {
return !predicate(value);
} Try / catch
try {
assert.not.undefined(value);
} catch (error) {
if (error instanceof TypeError) {
// value WAS of the disallowed type — report/reject at the boundary
return handleInvalidInput(error.message);
}
throw error;
} Prevention
- Use the boolean predicate form (`is.x(value)`) to branch when a disallowed type is an expected runtime case; reserve `assert.*` for genuine invariants
- Catch `TypeError` specifically at trust boundaries (API input, deserialization) and translate it into a user-facing validation error
- Include the offending field name in your wrapper's error so the message's type description is actionable
When it happens
Trigger: Calling `assertNotUndefined(value)` when `value` is undefined, `assertNotNull(x)` when `x` is null, `assertNotString`/`assertNotBoolean`/`assertNotSymbol`/`assertNotBigint`/`assertNotPrimitive` when the value is of that exact forbidden type.
Common situations: Optional data (missing object property, unset env var, `Map.get` miss) flowing into a code path that asserts presence with `assertNotUndefined`/`assertNotNull`; API responses with null fields; race conditions where a value isn't initialized yet.
Related errors
- Expected values which are ${orFormatter.format(uniqueExpecte
- Expected value which is `non-empty array`, received value of
- Expected value which is `non-empty map`, received value of t
- Expected value which is `non-empty object`, received value o
- Expected value which is `non-empty set`, received value of t
AI-assisted analysis of sindresorhus/is@7821031c66 (2026-07-31).
Data as JSON: /data/errors/ed0a0a0c48aafb68.json.
Report an issue: GitHub ↗.