awslabs/llrt · error · AssertionError
expected function to throw an error, but it didn't
Error message
expected function to throw an error, but it didn't
What it means
The synchronous path of toThrow throws this AssertionError when the supplied function executes without throwing any error, and no specific expected error was matched (expected not a string/regex/error). It is the sync counterpart of the promise variants in [7]/[8].
Solutions
- Make the function throw for the invalid case: add `throw new Error('...')` where appropriate.
- Pass a function/thunk to expect, not the invoked result: expect(() => fn()).toThrow().
- Verify the inputs actually trigger the throwing branch (e.g. truly invalid arguments).
- Update the test if non-throwing behavior is now correct, using toBe/toEqual instead.
Example fix
// before
function parse(n) { return Number(n); } // never throws
expect(() => parse('x')).toThrow();
// after
function parse(n) { const v = Number(n); if (Number.isNaN(v)) throw new Error('invalid number'); return v; }
expect(() => parse('x')).toThrow(); Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check the function throws before asserting
let threw = false; try { fn(); } catch { threw = true; } if (!threw) throw new Error('fn must throw for these inputs'); Try / catch
try { expect(() => fn()).toThrow(ExpectedError); } catch (e) { /* fn did not throw — fix fn or the inputs */ } Prevention
- Pass a thunk (() => fn()) to expect, never fn() result
- Make invalid inputs actually trigger throw branches
- Keep guard-clause refactors in sync with tests
- Assert a specific error class/message to catch silent behavior drift
When it happens
Trigger: expect(() => fn()).toThrow() where fn() completes normally; also expect(fn).toThrow() with a function reference that doesn't throw when invoked.
Common situations: Bug was fixed so the function no longer throws; guard clauses return early instead of throwing; input that should be invalid is silently coerced; test passed an already-invoked result instead of a thunk (e.g. expect(fn()).toThrow() with a resolved value).
Related errors
- expected promise to throw an error, but it didn't
- Expected is not a string
- You must provide an object to
- You must provide an array to
- any() expects to be passed a constructor function. Please…
AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12).
Data as JSON: /api/errors/cb6c79569ce29233.
Report an issue: GitHub.
Appendix: source
Thrown at llrt_core/src/modules/js/@llrt/expect/jest-expect.ts:467
return;
}
} else {
let isThrow = false;
try {
obj();
} catch (err) {
isThrow = true;
thrown = err;
}
if (!isThrow && !isNot) {
const message =
utils.flag(this, "message") ||
"expected function to throw an error, but it didn't";
const error = {
showDiff: false,
};
throw new AssertionError(message, error, utils.flag(this, "ssfi"));
}
}
if (typeof expected === "function") {
// @ts-ignore
const name = expected.name || expected.prototype.constructor.name;
return this.assert(
thrown && thrown instanceof expected,
`expected error to be instance of ${name}`,
`expected error not to be instance of ${name}`,
expected,
thrown
);
}
if (expected instanceof Error) {
return this.assert(
thrown && expected.message === thrown.message,View on GitHub (pinned to 742fc00b82)