TUI composer sometimes auto-fills with `codex(pid) MallocSt...` text

Resolved 💬 16 comments Opened Feb 12, 2026 by 0xWerz Closed Apr 3, 2026
💡 Likely answer: A maintainer (yuvrajangadsingh, contributor) responded on this thread — see the highlighted reply below.

Summary

Codex CLI TUI input sometimes auto-fills with text like:
codex(11033) MallocSt...

I did not type or paste this. The PID part changes over time (e.g. codex(8582), codex(10358), codex(11033)).

Screenshot

<img width="947" height="185" alt="image" src="https://github.com/user-attachments/assets/f814fef4-ed71-43f8-92fa-5412fbffc4f2" />

Environment

  • macOS
  • Codex CLI TUI

Steps to reproduce

Runtime repro (intermittent)

  1. Start Codex CLI TUI.
  2. Keep using it for a while (normal interaction, tool runs, shell output, etc.).
  3. Eventually the composer may auto-fill with codex(<pid>) MallocSt... text.

Expected behavior

Input should only contain user-typed or user-pasted text.

Actual behavior

Composer gets unexpected text that looks like allocator diagnostics.

Analysis / hypothesis

  • The text appears to match macOS malloc stack-logging diagnostics.
  • The changing PID supports that it is process-generated noise, not static input.
  • In terminals without reliable bracketed paste signaling, fast char streams can be classified as paste bursts. This likely lets diagnostic text leak into composer input as if it were pasted text.

Potential fix direction

  • Add a guard in paste-burst flush handling for this diagnostic shape.
  • Avoid silent data loss: if uncertain, quarantine as placeholder-backed pending paste rather than dropping content outright.

I can help validate fixes quickly on macOS if needed.

View original on GitHub ↗

16 Comments

vikjia · 5 months ago

same issue here, it annoyingly keeps overwriting my prompt

yuvrajangadsingh contributor · 5 months ago

I think I can help trace this — I worked on the paste burst detection code before (PR #9348).

The text codex(pid) MallocSt... is macOS malloc diagnostic output (from MallocStackLogging or related env vars). The changing PID confirms it's process-generated, not user input. Here's how I think it's reaching the composer:

How it enters the input stream:

Child processes spawned with StdioPolicy::Inherit in spawn.rs:116-121 inherit all three file descriptors from the parent:

StdioPolicy::Inherit => {
    cmd.stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit());
}

When a child process triggers malloc diagnostics (common on macOS when certain env vars are set or when memory tools are active), the diagnostic text gets written to the inherited stderr which shares the same TTY as the TUI. Depending on terminal buffering behavior, these bytes can end up in the input stream that crossterm reads from.

Why it gets classified as paste:

The diagnostic text arrives as a rapid burst of characters. The paste burst detector in paste_burst.rs:387-407 uses this heuristic in decide_begin_buffer():

let looks_pastey =
    grabbed.chars().any(char::is_whitespace) || grabbed.chars().count() >= 16;

Text like codex(11033) MallocStack... contains whitespace (the space after the PID) and is well over 16 characters, so it passes both checks. The burst detector treats it as pasted content and flushes it into the composer.

Potential fixes:

  1. Sanitize malloc env vars at startup — the process-hardening code in process-hardening/src/lib.rs already removes DYLD_* variables on macOS. Extending this to also unset MallocStackLogging, MallocStackLoggingNoCompact, MallocLogFile etc. would prevent the diagnostics from being emitted in the first place.
  1. Don't inherit stdin for child processes — changing StdioPolicy::Inherit to use Stdio::null() for stdin (while keeping stdout/stderr inherited) would reduce the surface for cross-contamination between child process output and TUI input.
  1. Filter diagnostic patterns in paste detection — add a guard in decide_begin_buffer() to reject text that matches known diagnostic patterns (e.g. contains Malloc). This is more of a band-aid though.

Option 1 seems like the cleanest fix since it addresses the root cause without changing stdio behavior.

ariccio · 4 months ago

Yeah, in seeing this too, among other tui garbling

yuvrajangadsingh contributor · 4 months ago

now that more people are hitting this, here's a concrete fix plan based on my earlier analysis above:

the cleanest approach is extending the process hardening code in codex-rs/process-hardening/src/lib.rs to also strip malloc diagnostic env vars (MallocStackLogging, MallocStackLoggingNoCompact, MallocLogFile, etc.) before spawning child processes. this already handles DYLD_* removal on macOS, so the pattern is established.

this kills the problem at the source instead of trying to filter diagnostic text downstream in the paste burst detector. the fix would be ~10 lines in one file.

i've worked on the paste burst detection code before (PR #9348, merged) and have the full context on how these bytes flow from child stderr into the TUI input stream. happy to submit a PR if invited. @joshka-oai @etraut-openai

gabewillen · 4 months ago

I'm also experiencing this issue in codex-cli 0.116.0

vonwao · 4 months ago

I've been seeing this also over the last week, quite a lot. Not a stopper, but pretty annoying

yuvrajangadsingh contributor · 4 months ago

@mbolin more reports coming in on this. I traced the root cause in my earlier comments, happy to put up a PR.

the fix is straightforward: strip MallocStackLogging, MallocStackLoggingNoCompact, MallocLogFile, and related Malloc* env vars in pre_main_hardening_macos() in codex-rs/process-hardening/src/lib.rs. the pattern is already there for DYLD_* removal, just needs the same treatment for malloc diagnostic vars.

this stops the noise at the source instead of trying to filter it out of the input stream later.

pHequals7 · 3 months ago

having the same issue - can we have a global level fix in the next update for this?

basnijholt · 3 months ago

I keep getting this issue. Currently on codex-cli 0.118.0 installed via bun (although that doesn't matter I guess) and on MacOS 26.3.1 (25D2128).

Let me know what else I can share to help debugging this.

basnijholt · 3 months ago

Here in 3 out of 9 instances I see this issue
<img width="2560" height="979" alt="Image" src="https://github.com/user-attachments/assets/356edb4c-314e-44b2-b8fc-8651687501bb" />

etraut-openai contributor · 3 months ago

Thanks for the bug report. This will be fixed in the next release.

jiabaogithub · 3 months ago

does it fixed? i also found this issue in ver v0.121.0(current latest version)

LiuDeng · 2 months ago

This issue still exists in v0.124.0

LiuDeng · 2 months ago

@etraut-openai

jamesx0416 · 2 months ago

Still happens in v0.125.0

yuvrajangadsingh contributor · 2 months ago

@etraut-openai the fix from #16699 is on main and shipped in v0.119.0+ (commit a71fc47cf8 — strips MallocStackLogging* and MallocLogFile* in pre_main_hardening_macos). but the recent reports here are all post-fix:

  • @jiabaogithub on v0.121.0 (apr 17)
  • @LiuDeng on v0.124.0 (apr 25)
  • @jamesx0416 on v0.125.0 (may 3)

so something else is still leaking the diagnostic into the composer. one likely path: the parent codex env is clean, but spawned shells source rc files (.zshrc, .bash_profile) that re-export MallocStackLogging=1, and that gets inherited by children of the shell. cmd.env_clear() at spawn.rs:75 doesn't help once the shell sources rc.

could we reopen this and either (a) strip Malloc* env vars from the child env in create_env/populate_env at codex-rs/protocol/src/shell_environment.rs even when inherit = All, or (b) invoke shells with --norc --noprofile for tool calls? happy to send a pr if you have a preference.

@jiabaogithub @LiuDeng @jamesx0416 a quick check that would help narrow this down: do any of you have MallocStackLogging set in your ~/.zshrc, ~/.bash_profile, or via launchctl getenv MallocStackLogging? a single env | grep -i malloc and launchctl getenv MallocStackLogging from the same shell that runs codex would tell us if it's coming from the shell init path.