Skip to content

Agent detection disables colors in user code via shared tinyrainbow singleton #10046

@christopher-buss

Description

@christopher-buss

Describe the bug

Vitest 4.1.2 calls disableDefaultColors() from tinyrainbow 3.1.0 when std-env's isAgent is true (e.g. running inside Claude Code, Cursor, etc.):

// vitest/dist/chunks/cac.DRKYQDPl.js
import { isAgent } from 'std-env';
import { disableDefaultColors } from 'tinyrainbow';

if (isAgent) disableDefaultColors();

disableDefaultColors() mutates tinyrainbow's shared default export singleton via Object.assign(), turning all color functions into identity functions. This affects not just Vitest's own output, but also user code under test that imports tinyrainbow — because both Vitest and user code resolve to the same singleton instance.

This means any test that asserts on ANSI-colored output (e.g. testing a CLI formatter that uses tinyrainbow) silently breaks when run inside an AI agent environment.

Reproduction

  1. Create a module that uses tinyrainbow:
import color from "tinyrainbow";
export const warn = (msg: string) => `${color.yellow("⚠")} ${msg}`;
  1. Write a test asserting colored output:
it("should produce yellow warning symbol", () => {
  expect(warn("oops")).toContain("\x1b[33m⚠\x1b[39m");
});
  1. Run with CLAUDECODE=1 (or any env that makes std-env detect an agent):
CLAUDECODE=1 vitest run

The test fails because color.yellow becomes an identity function.

Expected behavior: Vitest's agent detection should only affect Vitest's own reporter output, not mutate shared state that user code depends on.

Possible solutions:

  • Use createColors() for Vitest's internal rendering instead of mutating the default singleton
  • Scope the disable to Vitest's reporter layer rather than the global default

System Info

  System:
    OS: Windows 11 10.0.26100
    CPU: (32) x64 AMD Ryzen 9 9950X3D 16-Core Processor
    Memory: 37.30 GB / 93.64 GB
  Binaries:
    Node: 25.8.2 - C:\Users\Christopher\.local\share\mise\installs\node\25.8.2\node.EXE
    npm: 11.11.1 - C:\Users\Christopher\.local\share\mise\installs\node\25.8.2\npm.CMD
    pnpm: 10.33.0 - C:\Users\Christopher\.local\share\mise\installs\npm-corepack\0.34.6\pnpm.CMD
    bun: 1.3.11 - C:\Users\Christopher\.local\share\mise\installs\bun\1.3.11\bin\bun.EXE
    Deno: 2.7.10 - C:\Users\Christopher\.local\share\mise\installs\deno\2.7.10\bin\deno.EXE
  Browsers:
    Edge: Chromium (140.0.3485.54)
    Firefox: 149.0 - C:\Program Files\Mozilla Firefox\firefox.exe
  npmPackages:
    @vitest/coverage-v8: catalog:test => 4.1.2
    @vitest/eslint-plugin: catalog:lint => 1.6.13
    vitest: catalog:test => 4.1.2

Used Package Manager

pnpm

Validations


Generated with Claude Code
Verified manually by me!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions