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
- Remove `bodyEncoding` from any attachment that uses `path`.
- Use two distinct factory helpers: one for body attachments (sets bodyEncoding) and one for path attachments (omits it).
- 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
- Keep bodyEncoding coupled to body in factory code; never set it on path attachments.
- Run a normalize pass that strips bodyEncoding when path is present.
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
- Test attachment requires only one of "body" or "path" to be…
- Cannot annotate tests outside of the test run. The test
- Test attachment requires "body" or "path" to be set. Both…
- All browser instances within a project must use the same…
- `bench.compare()` expects every argument to be the return…
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)