(High Severity Uncaught TypeError): Unhandled Exception in `serializeError` on Anonymous or Eval Stack Frames
Issue :- (High Severity Uncaught TypeError): Unhandled Exception in serializeError on Anonymous or Eval Stack Frames
Metadata
- Title:
[Bug] Unhandled TypeError in serializeError when stack traces contain anonymous or eval call sites - Severity: High (Error Reporter Crash)
- Component: Error Serialization (
lib/serialize-error.js) - Affected File:
lib/serialize-error.js(extractSource, line 28–30)
Problem Summary
When a test fails and AVA formats the failure, serializeError(error) parses the stack trace with stack-utils to identify the originating test file and line number.
In extractSource, callSite is parsed for each stack frame. For frames originating from anonymous closures, eval, or native V8 dispatchers (e.g. at <anonymous>, at eval (eval at ...)), stackUtils.parseLine(line) returns an object where callSite.file is undefined.
The function then immediately calls normalizeFile(callSite.file). Inside normalizeFile:
file.startsWith('file://')
Because file is undefined, JavaScript throws:
TypeError: Cannot read properties of undefined (reading 'startsWith').
This unhandled exception inside the error serialization pipeline prevents the original assertion or test error from ever being reported, causing the worker process to crash with an internal failure.
Root Cause Analysis
In lib/serialize-error.js lines 15–38:
function normalizeFile(file, ...base) {
return file.startsWith('file://') ? file : pathToFileURL(path.resolve(...base, file)).toString();
}
const stackUtils = new StackUtils();
function extractSource(stack, testFile) {
if (!stack || !testFile) {
return null;
}
testFile = normalizeFile(testFile);
for (const line of stack.split('\n')) {
const callSite = stackUtils.parseLine(line);
if (callSite && normalizeFile(callSite.file) === testFile) { // <--- callSite.file can be undefined!
return {
isDependency: false,
isWithinProject: true,
file: testFile,
line: callSite.line,
};
}
}
return null;
}If any line in stack is:
at <anonymous>
stackUtils.parseLine produces:
{ line: undefined, column: undefined, file: undefined, function: '<anonymous>' }.
callSite is truthy, but callSite.file is undefined.
normalizeFile(undefined) executes undefined.startsWith(...), crashing with an unhandled TypeError.
Proposed Fix
Verify that callSite?.file is a non-empty string before passing it to normalizeFile:
--- a/lib/serialize-error.js
+++ b/lib/serialize-error.js
@@ -26,7 +26,7 @@ function extractSource(stack, testFile) {
for (const line of stack.split('\n')) {
const callSite = stackUtils.parseLine(line);
- if (callSite && normalizeFile(callSite.file) === testFile) {
+ if (callSite?.file && normalizeFile(callSite.file) === testFile) {
return {
isDependency: false,
isWithinProject: true,Source: avajs/ava