Skip to content

Inline image protocols (Kitty graphics, iTerm2) are silently dropped during shell initialization, but render correctly post-init #10020

@AlexisDotika

Description

@AlexisDotika

Describe the bug

Inline image-protocol escape sequences (Kitty graphics protocol and iTerm2 inline image protocol) emitted by a command running during shell initialization (e.g. from ~/.zshrc) are silently discarded by Warp. The exact same command, typed manually in the same tab after the shell prompt is shown, renders the image correctly.

This makes it impossible to use tools like fastfetch, neofetch, viu, imgcat, chafa (in image-protocol mode), etc. as part of a shell welcome banner — a common use case in other terminal emulators that support these protocols.

To reproduce

  1. Install fastfetch: brew install fastfetch
  2. Save any PNG to ~/test.png.
  3. Add this single line to ~/.zshrc:
    fastfetch --logo-type kitty-direct --logo "$HOME/test.png" --logo-width 22 --logo-height 22 --pipe false
  4. Open a new Warp tab.
    → Fastfetch's system info renders. No image is shown — fastfetch's built-in ASCII Apple logo appears in its place (this is fastfetch's silent fallback when an image protocol is unsupported).
  5. In the same tab (after the prompt is visible), manually type:
    fastfetch --logo-type kitty-direct --logo ~/test.png --logo-width 22 --logo-height 22 --pipe false
    → Fastfetch's system info and the PNG image render correctly via the Kitty graphics protocol.

The same contrast occurs with --logo-type iterm (iTerm2 inline image protocol) and --logo-type kitty: works post-init, fails during init.

Expected behavior

The image renders identically in both cases — during shell init and when typed manually. Other terminals supporting these protocols (iTerm2, WezTerm, Kitty, Ghostty) render the image at shell startup as documented in their respective specifications. The protocols themselves do not require the parser to be in any "post-prompt" or "interactive" state.

Screenshots, videos, and logs

Capturing fastfetch's stdout via > /tmp/init-output.bin directly inside ~/.zshrc reveals that during real shell initialization, fastfetch (with --logo-type kitty-direct ... --pipe false) emits a well-formed Kitty graphics escape sequence:

\e_Ga=T,f=100,t=f,c=22,r=22;<base64 of absolute image path>\e\

per the Kitty graphics protocol spec. The same invocation typed manually after the prompt renders the image correctly. Since fastfetch's stdout is the PTY connected to Warp, the byte stream reaching Warp is by construction identical in both contexts. The rendering difference therefore originates in Warp's processing of the same input depending on session state.

Operating system (OS)

macOS

Operating system and version

macOS Tahoe 26.2 (25C56) — arm64

Shell Version

zsh 5.9

Current Warp version

v0.2026.04.29.08.57.01

Regression

No — this has been the behavior for as long as I've been using Warp (months). I cannot identify a working version.

Additional context

Approaches tried that all fail to render the image at shell startup:

  • Switching protocol: iterm, kitty, kitty-direct — all silently fall back to the ASCII Apple logo at startup, all render correctly post-init.
  • Reordering: placing fastfetch before any prompt-manager initialization in .zshrc (a known fix for Powerlevel10k instant-prompt collisions in Kitty terminal — see fastfetch issue #485).
  • fastfetch --pipe false — forces emission regardless of TTY auto-detection. The escape sequences are emitted (verified via stdout capture, see logs section) but still not rendered by Warp.
  • Deferring via precmd zsh hook (post-init): output is suppressed by Warp's block UI.
  • Deferring via background subshell: ( sleep 0.2 && fastfetch ... ) &!. Even when output arrives well after the first prompt, Warp does not render the image.
  • Various sleep durations before fastfetch.

The only fallback that works at shell startup is pre-rendering the image with chafa --format symbols to a text file (Unicode block characters with truecolor ANSI escapes), which is plain text + color escapes — i.e. content that does not rely on the inline image-protocol parser.

Hypothesis: Warp's image-protocol parser is gated on a session state that is only entered after the first interactive command-output block is created. Output emitted during the shell-init phase is processed for normal text + ANSI color escapes, but the inline image protocols are silently dropped. The ( sleep N && fastfetch ) &! test (output arrives after first prompt yet still does not render) suggests the gating is stronger than simply "post-prompt".

This affects every common shell-startup banner tool (neofetch, fastfetch, macchina, viu-based banners, custom OSC scripts).

Does this block you from using Warp daily?

No

Is this an issue only in Warp?

Yes — the same setup renders correctly at shell startup in iTerm2, WezTerm, and Kitty per their documented protocol behavior.


If this gets triaged and labeled ready-to-implement, I'd be happy to have an Oz cloud agent take the implementation. I can verify the fix in my setup.

Metadata

Metadata

Assignees

Labels

area:shell-terminalTerminal input/output, shell integration, prompt behavior, and block rendering.bugSomething isn't working.os:macmacOS-specific behavior, regressions, or requests.ready-to-implementThe issue is ready for implementation work.repro:highThe report includes enough evidence that the issue appears highly reproducible.triagedIssue has received an initial automated triage pass.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions