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
- Remove the `bodyEncoding` field from any attachment that uses `path`.
- If you need `bodyEncoding`, switch from `path` to `body` (a string or Uint8Array).
- 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
- Use distinct builder functions for path-based vs body-based attachments so bodyEncoding never leaks.
- Add a unit test that asserts your attachment factory never emits both path and bodyEncoding.
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
- Test attachment requires "body" or "path" to be set. Both ar
- Test attachment requires only one of "body" or "path" to be
- bitLength is required
- Negative numbers are not supported
- Cannot compare screenshots without a test path
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/9a2fa66e27d6c347.json.
Report an issue: GitHub.