vitest-dev/vitest · error · TypeError

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

Error message

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

What it means

Thrown by manageArtifactAttachment when a TestAttachment sets `path` together with `bodyEncoding`. bodyEncoding only describes how the inline `body` string is encoded (base64 vs utf-8), so it is meaningless for a path-based attachment. Vitest enforces the invariant so downstream consumers do not try to decode a file path.

Solutions

  1. Remove `bodyEncoding` from any attachment that uses `path`.
  2. Use two distinct factory helpers: one for body attachments (sets bodyEncoding) and one for path attachments (omits it).
  3. Run a normalize step that deletes bodyEncoding whenever path is set.

Example fix

// before
attach({ path: '/tmp/log.txt', bodyEncoding: 'utf-8' })

// after
attach({ path: '/tmp/log.txt' })
Defensive patterns

Strategy: validation

Validate before calling

function normalizePathAttachment(a: TestAttachment) {
  if (a.path) delete a.bodyEncoding
  return a
}

Type guard

const pathHasNoEncoding = (a: TestAttachment) =>
  !a.path || !a.bodyEncoding

Try / catch

try {
  await ctx.annotate(msg, attachment)
} catch (e) {
  if (e instanceof TypeError && /bodyEncoding/i.test(e.message)) {
    delete attachment.bodyEncoding
    await ctx.annotate(msg, attachment)
  } else throw e
}

Prevention

When it happens

Trigger: Constructing an attachment like `{ path: '/tmp/x.png', bodyEncoding: 'base64' }` and passing it through context.annotate, recordArtifact attachments, or a custom artifact with attachments. Reusing a body-style attachment object and just adding a path without clearing bodyEncoding.

Common situations: Spreading a shared attachment template (`{ bodyEncoding: 'base64' }`) into path-based attachments; reporter/plugin code that always sets bodyEncoding regardless of source type.

Related errors


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

Appendix: 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 1fa9837ec2)