Skip to content

fix(claude): wait for a short image prompt's text before sampling the image baseline - #1226

Merged
Juliusolsson05 merged 2 commits into
mainfrom
fix/claude-image-literal-placeholder
Sep 25, 2026
Merged

Juliusolsson05 merged 2 commits into
mainfrom
fix/claude-image-literal-placeholder

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Problem (#1119, class C1)

A short (non-paste-like) prompt with an image attachment was written raw, and the image baseline was sampled immediately, before the text repainted. A prompt that literally names an image (why does [Image #1] look wrong) raised the placeholder count when it painted. The image poll took that for the attachment, and Enter went out with no image.

Change

deliverClaudeImagePrompt: both prompt shapes now write their text (bracketed for paste-like, raw for short) and wait for it to visibly enter the composer before pasting the image paths. This is the same pollPasteAbsorbed rule, with the same rollback on timeout, that the text-only path applies to every prompt. The image baseline therefore already counts any literal the text carries, so only a real pill can move it.

Tests (fail-first, recorded frames)

They use the recorded Claude Code 2.1.278 composer from the #1113 fixture:

  • The race the issue describes: the text paints one screen sample after the write, and the pill never renders. The old code writes Enter; the new code returns a failure without Enter.
  • Positive: a real pill renders after the literal, and delivery still submits. The fix doesn't work by refusing prompts that name an image.

The existing #1113 recorded tests still pass (src/providers/claude + src/shared/claude: 212 tests).

Verification

npx tsc -b clean.
Not verified here: a live Claude pane. A short image prompt now waits for its text to paint first, which normally takes tens of milliseconds.

Fixes #1119

🤖 Generated with Claude Code

Review disposition (A, B, C all Pi; 2 rounds)

Finding Disposition
A1/B1/C1 MAJOR: a whitespace-only prompt plus an image became a permanent do-not-retry (the text wait could never confirm) Fixed (c6496dba): a null tail needle skips the wait. Whitespace cannot carry an [Image #N] literal, so #1119 still holds. Tested, and the mutant is killed
B2/C2 MAJOR (tests): the image-path text timeout and rollback branch were untested (M12, M3 survived) Fixed: a recorded-frame test covers rollback and retry-same-session, with no image and no Enter
B3/C4: separator and short-prompt write shape unpinned (M4b, M5) Fixed: exact write sequence asserted
C3: an empty text baseline on the image path is undetectable (M7) Accepted residual: bounded consequence (an early image paste); stated in the round-2 brief
A2: a short prompt contained in Claude's dim suggestion never confirms Pre-existing on the text path; filed as #1230
B round 2: a paste-like whitespace prompt ("\n" plus an image) may merge two pastes Not a regression (that shape never worked); needs a live pane

Round 2: A, B and C all MERGE-READY.

Juliusolsson05 and others added 2 commits September 24, 2026 23:43
… image baseline

A short (non-paste-like) prompt with images was written raw, and the image
baseline was sampled immediately, before the text repainted. A prompt that
literally names an image ('why does [Image #1] look wrong') raised the
placeholder count when it painted, the image poll took that for the
attachment, and Enter went out with no image.

Both prompt shapes now wait until their text visibly entered the composer
(the same pollPasteAbsorbed rule the text-only path applies to every
prompt, with the same rollback on timeout) before the image paths are
pasted, so the baseline already counts any literal the text carries.

Test: the recorded Claude 2.1.278 frames from the #1113 fixture, with the
text painting one sample after the write (the race the issue describes)
and the pill never rendering. Old code writes Enter; new code does not.
A second case renders a real pill after the literal and still submits,
so the fix does not work by refusing prompts that name an image.

Fixes #1119

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t wait

Review of #1226: a " " + image send has no visible tail and never
collapses into a placeholder, so the new text wait could only time out
and the rollback could never see the bytes, a permanent do-not-retry
where main delivered. Whitespace cannot carry an [Image #N] literal, so
skipping the wait keeps the #1119 guarantee.

Adds coverage for the image-path text timeout (rollback + retry-same-
session), the trailing-whitespace separator and the raw short write.
Mutations killed: guard removed, rollback removed, failure branch dead,
separator always written, short prompt bracketed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
…round-1 fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05
Juliusolsson05 merged commit 46bf33c into main Sep 25, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the fix/claude-image-literal-placeholder branch September 25, 2026 07:58
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
…question, #1228/#1229 round 2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(claude): image absorption can confirm before any attachment renders, for a short prompt containing a literal [Image #N]

1 participant