avajs/ava · error · Error

All tests and hooks must be declared synchronously in your…

Error message

All tests and hooks must be declared synchronously in your test file, and cannot be nested within other tests or hooks.

What it means

Runner chain guard: test declarations (test(), hooks) were attempted after the runner already started executing — the test file declared tests asynchronously (after an await/timer) or nested a declaration inside another test/hook. AVA requires the full test plan to be registered synchronously at module load. The input at fault is the late or nested declaration call.

Solutions

  1. Move all test(), test.before/beforeEach/after calls to the top level of the test file
  2. Remove await/dynamic import before test declarations; perform async setup before any declaration or inside hooks
  3. Never declare tests inside another test's implementation; use hooks or serial tests instead
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at lib/runner.js:89 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02). Data as JSON: /api/errors/343d7ce1b7b806ad. Report an issue: GitHub.

Appendix: source

Thrown at lib/runner.js:89

		this.notifyTimeoutUpdate = timeoutMs => {
			this.emit('stateChange', {
				type: 'test-timeout-configured',
				period: timeoutMs,
			});
		};

		let hasStarted = false;
		let scheduledStart = false;
		const meta = Object.freeze({
			file: makeFileURL(options.file),
			get snapshotDirectory() {
				const {file, snapshotDir: fixedLocation, projectDir} = options;
				return makeFileURL(determineSnapshotDir({file, fixedLocation, projectDir}));
			},
		});
		this.chain = createChain((metadata, testArgs) => { // eslint-disable-line complexity
			if (hasStarted) {
				throw new Error('All tests and hooks must be declared synchronously in your test file, and cannot be nested within other tests or hooks.');
			}

			if (!scheduledStart) {
				scheduledStart = true;
				process.nextTick(() => {
					hasStarted = true;
					this.start();
				});
			}

			metadata.taskIndex = this.nextTaskIndex++;

			const {args, implementation, title} = parseTestArgs(testArgs);

			metadata.selected &&= this.checkSelectedByLineNumbers?.() ?? true;

			if (metadata.todo) {
				if (implementation) {

View on GitHub (pinned to bbfd946322)