Skip to content

supabase gen types corrupts redirected output with <claude-code-hint /> trailer when CLAUDECODE=1 #5212

@markbschonfeld-web

Description

@markbschonfeld-web

Bug report

Describe the bug

When the Supabase CLI is invoked with stdout redirected to a file inside an environment where CLAUDECODE=1 is set (e.g. inside Claude Code, or any agent harness that sets that env var), the resulting file is contaminated with a Claude Code plugin-hint trailer:

... legitimate generated TypeScript types ...

<claude-code-hint v="1" type="plugin" value="supabase@claude-plugins-official" />

That trailer makes the generated database.types.ts (or any other redirected output) fail to parse as TypeScript, breaking builds until the trailer is manually stripped.

This appears to have started when the CLI added Claude Code plugin-hint emission in v2.98.0+.

To Reproduce

  1. In any shell with CLAUDECODE=1 set (or running inside Claude Code), run:
    npx supabase@latest gen types typescript --project-id <some-project-id> > database.types.ts
  2. Open database.types.ts. The bottom of the file contains:
    <claude-code-hint v="1" type="plugin" value="supabase@claude-plugins-official" />
    
  3. tsc (or any TypeScript compiler) reports a parse error on that line.

Expected behavior

The hint should not contaminate the file written by > redirection. Two ways to satisfy this:

  1. Emit the hint to stderr (per the Claude Code plugin-hints documentation, which uses process.stderr.write(...) in its example), so shell redirection of stdout never picks it up.
  2. Skip emission when stdout is non-TTY (i.e. when output is being piped or redirected). Detecting non-interactive stdout is the standard CLI pattern for this.

Either fix would resolve the corruption without losing the install-prompt UX in the interactive case.

Workarounds

For anyone hitting this in the meantime:

  • CLAUDECODE='' npx supabase gen types typescript --project-id <id> > database.types.ts — unset the env var for the single command.
  • Pipe through sed to strip the hint: npx supabase gen types typescript --project-id <id> | sed '/<claude-code-hint/d' > database.types.ts
  • Strip after the fact: sed -i '/<claude-code-hint/d' database.types.ts

Environment

  • CLI version: 2.98.0+ (any version since the hint emission landed)
  • Affected commands: confirmed on gen types typescript; likely affects any other command whose stdout is the primary output (e.g. db dump, db diff)
  • Reproduces on: macOS, Linux, Windows (it's a shell-redirection issue, not platform-specific)

Reference

Per the Claude Code plugin-hints documentation:

When a CLI detects it's running in Claude Code (via the CLAUDECODE environment variable), it writes a self-closing <claude-code-hint /> tag to stderr.

Example from those docs:

if (process.env.CLAUDECODE) {
  process.stderr.write(
    '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',
  )
}

The Supabase CLI appears to be writing it to stdout instead, which is the source of the corruption.

Additional context

Claude Code does scan both stdout and stderr for these markers and strips them before they reach the model — so the trailer is invisible inside Claude Code's interactive flow. The corruption only surfaces when the user redirects stdout to a file with >, because the redirect captures the bytes before Claude Code's stripping pass runs.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions