vitest-dev/vitest · error · Error

Test runner doesn't support test artifacts.

Error message

Test runner doesn't support test artifacts.

What it means

`recordArtifact(task, artifact)` requires the active test runner to implement `onTestArtifactRecord`. If the current runner (obtained via `getRunner()`) does not expose that method (it is undefined), the call throws. This typically means the runner in use predates the artifact API or is a minimal/custom runner that never opted in.

Solutions

  1. Upgrade Vitest to a version whose runner implements `onTestArtifactRecord`.
  2. If using a custom runner, override `onTestArtifactRecord(task, artifact)` to persist/forward the artifact.
  3. Guard the call: `if (runner.onTestArtifactRecord) { await recordArtifact(...) }`.
  4. If artifacts are unsupported in your setup, remove the call or gate it behind a feature flag.

Example fix

// before
customRunner = { ...baseRunner } // no onTestArtifactRecord
await recordArtifact(task, { type: 'x', passed: true })

// after
customRunner = {
  ...baseRunner,
  async onTestArtifactRecord(task, artifact) {
    // persist and return the resolved artifact
    return artifact
  },
}
Defensive patterns

Strategy: type-guard

Validate before calling

const runner = getRunner(); if (typeof runner.onTestArtifactRecord !== 'function') throw new Error('runner does not support artifacts; upgrade Vitest or wire the method')

Type guard

function supportsArtifacts(runner: any): runner is { onTestArtifactRecord(task: Test, a: TestArtifact): Promise<TestArtifact> } { return typeof runner?.onTestArtifactRecord === 'function' }

Try / catch

try { await recordArtifact(task, artifact) } catch (e) { if (/doesn't support test artifacts/.test(e.message)) { /* skip or fallback */ return } throw e }

Prevention

When it happens

Trigger: Calling `recordArtifact(task, { type: 'my:artifact', ... })` while running under a runner that does not implement `onTestArtifactRecord` — e.g. a very old built-in runner, a third-party custom runner, or a node-environment runner that was constructed without the artifact reporter wired. The guard is at artifact.ts:72-74.

Common situations: Using `recordArtifact` (an `@experimental @advanced` API) with a stale Vitest version where the runner predates artifacts; a custom runner subclass that did not override `onTestArtifactRecord`; calling `recordArtifact` outside a properly initialized runner context (no server-side artifact sink).

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/runner/artifact.ts:73

    if (artifact.type === 'internal:annotation') {
      artifact.annotation.location = artifact.location
    }
  }

  if (Array.isArray(artifact.attachments)) {
    for (const attachment of artifact.attachments) {
      manageArtifactAttachment(attachment)
    }
  }

  // annotations won't resolve as artifacts for backwards compatibility until next major
  if (artifact.type === 'internal:annotation') {
    return artifact
  }

  if (!runner.onTestArtifactRecord) {
    throw new Error(`Test runner doesn't support test artifacts.`)
  }

  await finishSendTasksUpdate(runner)

  const resolvedArtifact = await runner.onTestArtifactRecord(task, artifact)

  task.artifacts.push(resolvedArtifact)

  return resolvedArtifact as typeof artifact
}

const table: string[] = []
for (let i = 65; i < 91; i++) {
  table.push(String.fromCharCode(i)) // A-Z
}
for (let i = 97; i < 123; i++) {
  table.push(String.fromCharCode(i)) // a-z
}

View on GitHub (pinned to 1fa9837ec2)