[BUG] `claude --resume` crashes with `g9H is not a function` when restoring a session

Resolved 💬 4 comments Opened Apr 25, 2026 by buley Closed Apr 27, 2026

Bug: claude --resume crashes with g9H is not a function when restoring a session

Summary

Resuming any saved session via claude --resume <session-id> (or selecting a session from the picker) crashes immediately with:

ERROR  g9H is not a function. (In 'g9H(K)', 'g9H' is undefined)
 /$bunfs/root/src/entrypoints/cli.js:9251:5663

The CLI fails before any session content is rendered, so resuming is completely broken.

Environment

  • Claude Code: 2.1.120
  • Platform: macOS 15 (Darwin 24.5.0, arm64)
  • Shell: zsh
  • Repro: 100%, on every saved session in this project.

Repro

  1. Run claude in a project with prior sessions on disk under ~/.claude/projects/<project-slug>/*.jsonl.
  2. Pick any session to resume (or pass --resume <id> directly).
  3. Crash on mount, before the transcript renders.

Affected session in my case: ~/.claude/projects/-Users-buley-Documents-Code-emotions/b36b8ec7-5177-4d44-81d5-ad237dae3eec.jsonl (~2.8 MB, ordinary transcript — nothing exotic in the content).

Root cause (from the minified stack)

In src/entrypoints/cli.js around line 9251, the REPL component destructures session-restore callbacks from a hook:

let { onBeforeQuery: F9H,
      onTurnComplete: ZLH,
      onSessionRestored: g9H,
      render: aM_,
      ownsInput: LLH } = FXK({ enabled: S, /* ... */ });

S is hardcoded to false a few lines above:

S = s_.useMemo(() => !1, []),

So FXK({ enabled: false, ... }) returns an object that does not include onSessionRestored, and g9H is undefined.

Later, on the mount effect that handles initial messages, the code calls it unconditionally:

s_.useEffect(() => {
  if (K && K.length > 0)
    HP_(K, K8()),
    hY8({ abortController: new AbortController, taskRegistry: YH }),
    tC8(K),
    UQ(K),
    sYH.current.current = xz_(K, g8),
    g9H(K);                       // <-- crash here when g9H is undefined
}, []);

Because K (the initial message array) is non-empty for any resumed session, this path is always taken on resume, and the unguarded g9H(K) throws.

Why it presumably worked before

Whatever feature S (enabled) gates was likely turned on in earlier builds. When it was flipped off (useMemo(() => !1, []) smells like a deliberate kill-switch for an experimental subsystem), the producer side of the hook started returning a partial object, but the consumer side that calls onSessionRestored was not wrapped in the same guard.

Suggested fix

One of:

  1. Guard the call site: g9H?.(K).
  2. Have FXK always return a no-op onSessionRestored (and the other callbacks) when enabled is false, so destructured fields are never undefined.
  3. Tie the if (K && K.length > 0) block to the same enabled flag.

Option (1) is the smallest patch and matches what the surrounding callbacks (F9H, ZLH) appear to need too — if enabled is false, those are presumably also undefined and would crash the moment the user submits a turn or completes one. Worth auditing all five destructured fields from FXK for the same pattern.

Full stack trace

ERROR  g9H is not a function. (In 'g9H(K)', 'g9H' is undefined)

 /$bunfs/root/src/entrypoints/cli.js:9251:5663
 - <anonymous>  (cli.js:9251:5663)
 - WC           (cli.js:492:63749)
 - pj           (cli.js:492:76948)
 - fT           (cli.js:492:76827)
 - pj           (cli.js:492:76926)
 - fT           (cli.js:492:76827)
 - pj           (cli.js:492:77745)
 - fT           (cli.js:492:76827)
 - pj           (cli.js:492:76926)
 - fT           (cli.js:492:76827)

Workaround

Sessions on disk are still readable as JSONL — content is intact. Starting a fresh claude session and reading the prior transcript file directly (Read tool on the .jsonl) recovers context, but --resume itself is unusable on 2.1.120.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗