Skip to content

🤖 fix: a failed branch list says so in the creation view, and Run /init waits for it - #6417

Merged
ThomasK33 merged 2 commits into
mainfrom
fix/6055-creation-branch-load-state
Oct 13, 2026
Merged

ThomasK33 merged 2 commits into
mainfrom
fix/6055-creation-branch-load-state

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Summary

The creation view now tells a failed branch list apart from an empty one. A rejected listBranches, or one with no answer within 15 s, shows "Could not load branches" where the branch picker was, and Send stays off for every runtime except Local. The "Run /init" banner is now off while the creation composer cannot send, so a click is never left unsent.

Fixes #6055
Fixes #6038

Background

Silent switch to Local (the main defect in #6055). When listBranches rejected, useCreationWorkspace still marked the branches loaded, with none. CreationControls reads "loaded, no branches" as a non-git repo, so its runtime effect switched the selection to Local without telling the user, and Send then created a Local (project-directory) workspace instead of a worktree. The issue text expected the old "Trunk branch is required" toast. In fact no toast appeared, and the workspace was created on the wrong runtime. A listBranches that never settled kept Send off with only the picker skeleton, forever.

#6038. "Run /init" sends through the creation composer once. Since #6035 that send is refused while the branch list loads, so the click left /init in the composer unsent.

Implementation

  • branchListLoad.ts (new): startBranchListLoad runs one load and reports loaded or failed. It reports failed on a reject or after BRANCH_LIST_TIMEOUT_MS (15 s). A list that answers after the deadline still reports loaded, so a slow list recovers. It returns a cancel function, so a remount reports nothing stale.
  • useCreationWorkspace: branchesLoaded: boolean becomes branchLoad: "loading" | "loaded" | "failed", loaded through startBranchListLoad and cancelled in the effect cleanup. The unused reloadBranches callback (no callers, and no mounted guard: 🤖 fix: creation view Send has no feedback when the branch list hangs or fails #6055 item 3) is removed.
  • CreationControls: only a loaded empty list means non-git, so a failed list never switches the runtime. A small SourceBranchPicker shows the skeleton, the select, or the failure text.
  • ChatInput: the Send gate is open only when branchLoad === "loaded" (or the runtime is Local), and the composer reports that gate to the page (useReportCreationSendBlocked).
  • ProjectPage and AgentsInitBanner: "Run /init" is disabled until the composer reports it can send. It starts disabled.

Decisions (from the issue coordinator): fail closed, with no Retry button, because reopening the project retries (the view remounts per project). The failure state adds no new operation, so it needs no shortcut. The only new copy is "Could not load branches".

Validation

Tests failed on main for the stated reason and pass after the fix (tests/ui/agents/creationWaitsForBranches.test.ts, 7 of 7):

  • "Run /init is off while the branches load, then a click sends /init at once". On main: Expected: true, Received: false (the button was enabled).
  • "a failed branch list says so and keeps a worktree send off, with no switch to Local". On main: no failure text, and the page read "Workspace Type Local".
  • "a branch list that hangs past the bound says so". On main: no failure text after the bound.
  • The 🤖 fix: Send in a creation view before its branch list loads fails with "Trunk branch is required" #6033 tests still pass: the worktree gate, the runtime-probe independence, the Local case, and Run /init after load.

branchListLoad.test.ts (new, fake timers) covers in time, reject, the deadline then a late answer, and cancel. The ChatInput unit tests give 171 pass, 0 fail.

Dogfood (production build, mock AI, a git wrapper that fails or hangs on for-each-ref):

State Build Runtime Send Run /init
list fails main Local (silent switch) on on
list fails this PR Worktree off, "Could not load branches" off
list loading main Worktree off on
list loading this PR Worktree off off
list loaded this PR Worktree on on

Before, failed list (main, 1280 px):
Before: a failed branch list switched the runtime to Local and left Send on

After, failed list (1280 px):
After: Could not load branches, Worktree kept, Send off

After, failed list (390 px):
After at 390 px: Could not load branches

Before, list loading (main, Run /init enabled):
Before: Run /init enabled while the branch list loads

After, list loading (Run /init disabled):
After: Run /init disabled while the branch list loads

After, list loaded:
After: Run /init and Send enabled once the list loaded

Risks

Low. Only the creation view changes. A list that answers within 15 s behaves as before. The Local runtime is never gated. Projects that really are non-git still switch to Local, because a loaded empty list keeps that meaning.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $305.66

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-13T22:23:57.594683Z 1e1199c New commits
🔒 Security Review ✅ Completed 2026-10-13T22:24:25.283050Z 1e1199c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80359eb29b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/components/ProjectPage/ProjectPage.tsx Outdated
…it waits for it

A creation view whose listBranches rejected marked the branches loaded
with none, so the git project looked like a non-git one: the runtime
silently switched to Local and Send created a Local workspace (#6055).
A list that never settled kept Send off with no explanation. The view
now tracks the branch list as loading, loaded or failed. A reject, or
no answer within 15 s, shows "Could not load branches" in place of the
picker and keeps Send off for every runtime except Local; a list that
answers late still loads. The dead git-init reloadBranches callback,
which had no mounted guard, is removed.

The "Run /init" banner sends through the creation composer once, so it
is now off while that composer cannot send, instead of leaving /init
unsent (#6038).

Fixes #6055
Fixes #6038

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
ProjectPage is reused across projects and drafts while its composer
remounts per scope, so the first render of a new scope still showed the
previous scope's "can send" and Run /init was enabled until the new
composer reported. The flag is now scoped to the composer key and reset
during render when the key changes.

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
@ThomasK33
ThomasK33 force-pushed the fix/6055-creation-branch-load-state branch from 80359eb to 1e1199c Compare October 13, 2026 22:21
@ThomasK33

Copy link
Copy Markdown
Member Author

Perf clearance (perf owner): cleared at 1e1199c5a7.

  • The head matches git ls-remote. The merge base is 7c6e7fdd9f. The changed lines match the request.
  • React Compiler at base and head: ChatInput (index.tsx), CreationControls, AgentsInitBanner and both new hooks compile. ProjectPage and useCreationWorkspace keep their existing bailouts (for-await and try/finally, already on main), so this PR adds no new bailout.
  • Per keystroke, ChatInput adds one string comparison. The report effect runs only when its inputs change.

Non-blocking note: ProjectPage is not compiled, so setCreationSendBlocked is a new function on every ProjectPage render. The composer's report effect then runs once per page render, and the setter returns the same state, so it causes no extra render. That costs microseconds on renders that already happen.

A new head needs a new clearance.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 832a317 Oct 13, 2026
62 of 64 checks passed
@ThomasK33
ThomasK33 deleted the fix/6055-creation-branch-load-state branch October 13, 2026 22:49
yermakoffivan pushed a commit to yermakoffivan/mux that referenced this pull request Oct 14, 2026
…oder#6458)

## Summary

The creation view's "Run /init" button is now off whenever the creation
composer cannot send, not only while the branch list loads. While Coder
presets load, a send is in flight, attachments are processing or the
composer is disabled, a click used to be refused by the composer and
left `/init` unsent.

Fixes coder#6423

## Background

"Run /init" restores `/init` in the creation composer and calls its
`send()` once. coder#6417 (fix for coder#6038) turned the button off while the
branch list loads or has failed, but `canSend` has more blockers. The
final check of coder#6417 found the gap and coder#6423 tracked it.

## Implementation

`useReportCreationSendBlocked` now takes the same blockers that
`canSend` checks: `disabled`, a send in flight, processing attachments,
Coder presets loading, and the branch list. It leaves out an empty
draft, because the banner brings its own text. The page side
(`useCreationSendBlocked` in ProjectPage, scoped per composer) is
unchanged. The blockers are combined inside the hook, so
`ChatInputInner` gains no complexity (CRAP gate).

## Validation

Two new tests in `tests/ui/agents/creationWaitsForBranches.test.ts`
(real backend) failed on main with `Expected: true, Received: false`
(the button was enabled) and pass now:
- "Run /init is off while the Coder presets load": `CoderService`
reports an available CLI and one template, and `listPresets` is held.
After the user picks the Coder runtime, the button turns off, and it
turns on again when the presets load.
- "Run /init is off while a send is in flight":
`WorkspaceService.create` is held after a Send click. The button stays
off while the send is in flight.

The file passes 9 of 9 (the coder#6033, coder#6055 and coder#6038 tests still pass).
The ChatInput and ProjectPage unit tests give 186 pass, 0 fail.

Dogfood (production build, mock AI, `git worktree` held so the creation
send stays in flight). Run /init during the send: main **enabled**, this
PR disabled (1280 and 390 px).

Before, send in flight (main, 1280 px):
![Before: Run /init enabled while a creation send is in
flight](https://github.com/user-attachments/assets/24ed7a23-0105-4857-8a51-b18944cdb2da)

After, send in flight (1280 px):
![After: Run /init disabled while a creation send is in
flight](https://github.com/user-attachments/assets/c8c629ff-3135-469e-83dc-bb1901b0df90)

After, send in flight (390 px):
![After at 390 px: Run /init disabled while a creation send is in
flight](https://github.com/user-attachments/assets/e32d2b8e-4570-47b4-a781-133e6359f7f1)

First-load JS (`make first-load-js`, base 9aec386 vs this head):
total raw 2,266.8 KiB on both, brotli 455.3 KiB to 455.5 KiB, gzip 558.2
KiB to 558.3 KiB.

## Risks

Low. Only the creation page banner reads the report. A workspace
composer reports nothing.

---

_Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking:
`high` • Cost: `$324.26`_

<!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high
costs=324.26 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant