vitest-dev/vitest · error · Error

Test runner doesn't support test annotations.

Error message

Test runner doesn't support test annotations.

What it means

Thrown from context.annotate when the active VitestRunner has no `onTestAnnotate` method. Annotation support is opt-in for custom runners; the built-in runners implement it, but a hand-rolled VitestRunner subclass may not. The error fires at annotation time, not at runner registration.

Solutions

  1. Implement `onTestAnnotate(test, annotation)` on your custom VitestRunner subclass.
  2. Switch to the built-in runner (e.g., VitestTestRunner) which supports annotations.
  3. If you cannot change the runner, avoid ctx.annotate and record metadata via expect or custom logging instead.

Example fix

// before
class MyRunner extends VitestRunner {
  // missing onTestAnnotate
}

// after
class MyRunner extends VitestRunner {
  onTestAnnotate(test, annotation) {
    test.annotations.push(annotation)
    return annotation
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

const runnerSupportsAnnotations = (r: VitestRunner) =>
  typeof (r as any).onTestAnnotate === 'function'

Type guard

function supportsAnnotate(r: VitestRunner): r is VitestRunner & { onTestAnnotate: NonNullable<VitestRunner['onTestAnnotate']> } {
  return typeof r.onTestAnnotate === 'function'
}

Prevention

When it happens

Trigger: Subclassing VitestRunner without overriding onTestAnnotate; using a third-party runner that predates the annotation API; calling ctx.annotate inside a test driven by a minimal custom runner.

Common situations: Building a custom runner for a non-standard environment (e.g., embedded, proprietary harness); pinning an old runner version while the test code uses new annotation APIs.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/ddb02d47e6ee34a1. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/runtime/runner/context.ts:211

    }

    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) {
          throw new Error(`Test runner doesn't support test annotations.`)
        }

        await finishSendTasksUpdate(runner)

        const resolvedAnnotation = await runner.onTestAnnotate(test, annotation)
        test.annotations.push(resolvedAnnotation)
        return resolvedAnnotation
      }),
    )
  }) as TestContext['annotate']

  context.onTestFailed = (handler, timeout) => {
    test.onFailed ||= []
    test.onFailed.push(
      withTimeout(
        handler,
        timeout ?? runner.config.hookTimeout,
        true,

View on GitHub (pinned to 1fa9837ec2)