vitest-dev/vitest · error · Error
Cannot annotate tests outside of the test run. The test "${t
Error message
Cannot annotate tests outside of the test run. The test "${test.name}" finished running with the "${test.result.state}" state already. What it means
The `context.annotate()` method attaches metadata annotations to a test, but it can only be called while the test is actively running (state `'run'`). If the test has already settled into a final state (`pass`, `fail`, `skip`), calling `annotate` throws this error (context.ts:190-192). This prevents annotating tests from deferred/async code that outlives the test's execution window.
Source
Thrown at packages/vitest/src/runtime/runner/context.ts:192
context.task = test
context.skip = (condition?: boolean | string, note?: string): never => {
if (condition === false) {
// do nothing
return undefined as never
}
test.result ??= { state: 'skip' }
test.result.pending = true
throw new PendingError(
'test is skipped; abort execution',
test,
typeof condition === 'string' ? condition : note,
)
}
context.annotate = ((message, type, attachment) => {
if (test.result && test.result.state !== 'run') {
throw new Error(`Cannot annotate tests outside of the test run. The test "${test.name}" finished running with the "${test.result.state}" state already.`)
}
const annotation: TestAnnotation = {
message,
type: typeof type === 'object' || type === undefined ? 'notice' : type,
}
const annotationAttachment = typeof type === 'object' ? type : attachment
if (annotationAttachment) {
annotation.attachment = annotationAttachment
manageArtifactAttachment(annotation.attachment)
}
return recordAsyncOperation(
test,
recordArtifact(test, { type: 'internal:annotation', annotation }).then(async ({ annotation }) => {
if (!runner.onTestAnnotate) {View on GitHub (pinned to d568f8ce37)
Solutions
- Ensure `annotate()` is called synchronously within the test body or within a properly awaited async flow before the test returns.
- Move annotation logic that depends on deferred results into `onTestFinished`/`onTestFailed` handlers registered during the test.
- Await any promise that calls `annotate` before letting the test function return.
- If annotating from a hook, use the hook's own context rather than a stale captured test context.
Example fix
// before
test('x', ({ annotate }) => {
setTimeout(() => annotate('late note'), 100) // test finishes first
})
// after
test('x', async ({ annotate }) => {
await new Promise(r => setTimeout(r, 100))
annotate('timely note')
}) Defensive patterns
Strategy: validation
Validate before calling
function canAnnotate(test: { result?: { state?: string } }): boolean {
return !test.result || test.result.state === 'run'
}
// usage inside a deferred callback:
if (canAnnotate(context.task)) {
context.annotate('note')
} Type guard
function testIsRunning(test: { result?: { state?: string } }): test is { result: { state: 'run' } } {
return test.result?.state === 'run'
} Try / catch
try {
context.annotate('maybe-late')
} catch (e) {
if (e instanceof Error && /Cannot annotate tests outside/.test(e.message)) {
// test already finished; annotation is moot, swallow or log
} else throw e
} Prevention
- Always await any promise that calls annotate before the test returns.
- Prefer annotating synchronously at the point the information is known.
- Avoid fire-and-forget timers that call annotate.
When it happens
Trigger: Calling `context.annotate(...)` inside a `setTimeout`/`setInterval`/microtask that fires after the test resolved; annotating inside `onTestFailed`/`onTestFinished` hooks on a context whose test already finished; awaiting a fire-and-forget promise that calls annotate after the test ends.
Common situations: Fire-and-forget async operations that outlive the test; annotation in cleanup hooks; race conditions where the test completes before a background annotation call resolves.
Related errors
- Cannot take a screenshot outside of a test.
- 'toMatchScreenshot' cannot be used without test context
- expect.poll() must be called inside a test
- Hook ${name}() can only be called inside a test
- Cannot call "onTestFailed" inside a test hook.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/797c705a520cb0f0.json.
Report an issue: GitHub.