vitest-dev/vitest · error · TypeError

Test attachment with "path" should not have "bodyEncoding" s

Error message

Test attachment with "path" should not have "bodyEncoding" specified.

What it means

When recording a test artifact with an attachment, Vitest requires that a path-based attachment (pointing to a file on disk) must not specify a `bodyEncoding` field. `bodyEncoding` (e.g. 'base64') only applies to inline `body` content. This is enforced in `manageArtifactAttachment` (artifact.ts:170) which validates each attachment's shape before serialization, alongside checks that exactly one of `body`/`path` is present.

Source

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

/**
 * Validates and prepares a test attachment for serialization.
 *
 * This function ensures attachments have either `body` or `path` set (but not both), and converts `Uint8Array` bodies to base64-encoded strings for easier serialization.
 *
 * @param attachment - The attachment to validate and prepare
 *
 * @throws {TypeError} If neither `body` nor `path` is provided
 * @throws {TypeError} If both `body` and `path` are provided
 */
export function manageArtifactAttachment(attachment: TestAttachment): void {
  if (attachment.body == null && !attachment.path) {
    throw new TypeError(`Test attachment requires "body" or "path" to be set. Both are missing.`)
  }
  if (attachment.body && attachment.path) {
    throw new TypeError(`Test attachment requires only one of "body" or "path" to be set. Both are specified.`)
  }
  if (attachment.path && attachment.bodyEncoding) {
    throw new TypeError(`Test attachment with "path" should not have "bodyEncoding" specified.`)
  }
  // convert to a string so it's easier to serialise
  if (attachment.body instanceof Uint8Array) {
    attachment.body = encodeUint8Array(attachment.body)
  }
  if (attachment.body != null) {
    attachment.bodyEncoding ??= 'base64'
  }
}

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Remove the `bodyEncoding` field from any attachment that uses `path`.
  2. If you need `bodyEncoding`, switch from `path` to `body` (a string or Uint8Array).
  3. Ensure attachment builders are mutually exclusive: never set `bodyEncoding` when `path` is defined.

Example fix

// before
await recordArtifact(test, {
  type: 'report',
  attachments: [{ path: '/tmp/result.json', bodyEncoding: 'base64' }],
})
// after
await recordArtifact(test, {
  type: 'report',
  attachments: [{ path: '/tmp/result.json' }],
})
Defensive patterns

Strategy: validation

Validate before calling

function isValidAttachment(a: { body?: unknown; path?: string; bodyEncoding?: string }) {
  if (a.path && a.bodyEncoding) return false
  return true
}
// before recording:
for (const a of artifact.attachments ?? []) {
  if (!isValidAttachment(a)) throw new Error('Remove bodyEncoding from path-based attachment')
}

Type guard

function isPathAttachmentWithoutEncoding(a: any): a is { path: string; body?: undefined; bodyEncoding?: undefined } {
  return typeof a.path === 'string' && a.body == null && a.bodyEncoding == null
}

Prevention

When it happens

Trigger: Calling `recordArtifact(task, { attachments: [{ path: '/some/file.txt', bodyEncoding: 'base64' }] })` or `context.annotate(message, { attachment: { path, bodyEncoding } })` — any attachment object reaching `manageArtifactAttachment` with both `path` truthy and `bodyEncoding` set.

Common situations: Copy-pasting attachment configuration between body-based and path-based attachments; building attachments dynamically where a default `bodyEncoding: 'base64'` leaks into path-based ones; migrating from body to path attachments without dropping bodyEncoding.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/9a2fa66e27d6c347.json. Report an issue: GitHub.