Skip to content

Fix board view crash when feature status lags during race conditions#825

Merged
gsxdsm merged 4 commits intoAutoMaker-Org:v1.0.0rcfrom
gsxdsm:fix/board-crash-new-feat
Mar 3, 2026
Merged

Fix board view crash when feature status lags during race conditions#825
gsxdsm merged 4 commits intoAutoMaker-Org:v1.0.0rcfrom
gsxdsm:fix/board-crash-new-feat

Conversation

@gsxdsm
Copy link
Collaborator

@gsxdsm gsxdsm commented Mar 3, 2026

Summary

  • Fixed React error fixing worktree style #185 (maximum update depth exceeded) that caused infinite spinner crash when features transitioned to in_progress in board view
  • Removed duplicate WebSocket event handling in useBoardFeatures that triggered cascading re-renders through DndContext
  • Added memoization to KanbanBoard component to prevent unnecessary re-render propagation
  • Improved handling of stale feature status during race conditions when status updates lag

Changes

Board View Crash Fix

  • Removed duplicate cache invalidation in useBoardFeatures hook for auto_mode_feature_start events - useAutoModeQueryInvalidation already handles this centrally, preventing cascade re-renders through DndContext
  • Wrapped KanbanBoard in memo() to prevent parent re-renders from propagating through the entire DndContext subtree
  • Added detailed comments explaining the re-render cascade issue to prevent future regressions

Handling Stale Feature Status During Race Conditions

  • Updated board view row click handler to check if feature is actively running (tracked in runningAutoTasksAllWorktrees) even if status is stale (still showing 'backlog'/'ready'/'interrupted')
  • Added menu item block in RowActions for running tasks with stale status - displays "View Logs", "Edit", "Spawn Sub-Task", and "Force Stop" options
  • Features in in_progress column now correctly show logs/actions even if status field hasn't updated yet during WebSocket/database sync delays

Specification Parser Improvements

  • Fixed extractSummary() regex to stop at same-level ## Headers but preserve ### Subsections within Summary sections
  • Updated truncation logic to keep full content up to 500 chars instead of cutting at subsection boundaries
  • Added tests covering ### Root Cause and ### Fix Applied subsections to remain in extracted summary
  • Updated test expectations to include all paragraphs in Summary sections rather than just the first

Summary by CodeRabbit

  • New Features

    • Force Stop option for running tasks; View Logs and Spawn Sub-Task actions available during runs.
  • Improvements

    • Summary extraction preserves nested subsections and multiple paragraphs, now length-capped.
    • Editing blocked for actively running items; viewing output/logs prioritized during race-window.
    • Hook click URLs now include board deep-linking when applicable.
  • Performance

    • Fewer unnecessary UI reloads; Kanban board memoized to reduce re-renders.
  • Tests

    • Added/updated tests for summary extraction and deep-link behavior.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the stability and user experience of the board view by addressing critical rendering issues and improving how feature statuses are managed during rapid updates. It also refines the specification parsing logic to provide more comprehensive summaries, ensuring that important contextual information within subsections is not inadvertently truncated. These changes collectively lead to a more robust and accurate display of feature progress and details.

Highlights

  • Board View Stability: Resolved a React error (fixing worktree style #185) that caused an infinite spinner crash in the board view when features transitioned to 'in_progress' due to race conditions.
  • Performance Optimization: Eliminated duplicate WebSocket event handling in useBoardFeatures and applied memoization to the KanbanBoard component to prevent cascading re-renders.
  • Stale Status Handling: Improved the board view's ability to handle features with stale statuses, ensuring correct actions and logs are displayed even if the status field hasn't updated yet.
  • Specification Parser Enhancement: Updated the extractSummary() regex to correctly include subsections (e.g., ### Root Cause) within the summary and to preserve full content up to 500 characters.
  • Test Coverage: Added new unit tests for the specification parser to validate the improved summary extraction logic, including subsections and multiple paragraphs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • apps/server/src/services/spec-parser.ts
    • Updated the regex for extractSummary() to correctly identify the end of a ## Summary section, allowing ### subsections to be included.
    • Modified the truncation logic in extractSummary() to retain full content up to 500 characters, including any nested subsections.
  • apps/server/tests/unit/services/spec-parser.test.ts
    • Added new test cases to verify that extractSummary() correctly includes ### subsections and stops at the next ## header.
    • Updated an existing test case to confirm that extractSummary() now includes all paragraphs within a ## Summary section, not just the first.
  • apps/ui/src/components/views/board-view.tsx
    • Adjusted the onRowClick handler to check for actively running tasks (isRunning) in addition to the feature's reported status, ensuring that logs are shown for running tasks even if their status is temporarily stale.
  • apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx
    • Introduced a new menu block in RowActions to provide appropriate actions (View Logs, Edit, Spawn Sub-Task, Force Stop) for running tasks that still display stale 'backlog-like' statuses.
  • apps/ui/src/components/views/board-view/hooks/use-board-features.ts
    • Removed duplicate WebSocket event handling for auto_mode_feature_start and auto_mode_feature_complete events, as query invalidation is now centrally managed by useAutoModeQueryInvalidation, preventing re-render cascades.
  • apps/ui/src/components/views/board-view/kanban-board.tsx
    • Wrapped the KanbanBoard component with memo to optimize rendering performance and prevent unnecessary re-renders from parent components.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

Server spec summary extraction now preserves nested "###" subsections and truncates Summary to 500 characters; tests updated. UI: added isBacklogLikeStatus, adjusted row-click and row-actions for running-but-stale backlog-like tasks, removed redundant feature reloads on auto-mode events, and memoized KanbanBoard.

Changes

Cohort / File(s) Summary
Spec Parser & Tests
apps/server/src/services/spec-parser.ts, apps/server/tests/unit/services/spec-parser.test.ts
extractSummary updated to stop at the next same-level ## header while preserving nested ### subsections and to truncate output to 500 characters (with ...). Tests added/updated to cover nested subsections, multiple paragraphs, and top-level stop behavior.
Board view core & constants
apps/ui/src/components/views/board-view.tsx, apps/ui/src/components/views/board-view/constants.ts
Imported/added isBacklogLikeStatus and changed row-click handling to enter edit only for backlog-like statuses when the feature is not running; otherwise open view output.
Row actions menu
apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx
Added conditional block for running-but-stale backlog-like tasks to surface actions (View Logs, Edit, Spawn Sub-Task, Force Stop) using isBacklogLikeStatus.
Hooks / invalidation
apps/ui/src/components/views/board-view/hooks/use-board-features.ts
Removed direct loadFeatures() calls from auto-mode start/complete event handlers; kept completion ding and error handling; rely on centralized invalidation to avoid render cascades.
KanbanBoard memoization
apps/ui/src/components/views/board-view/kanban-board.tsx
Wrapped exported KanbanBoard with React.memo (imported memo) to reduce re-renders; public API unchanged except wrapper.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Testers-Requested

Poem

🐰 I nibbled headers, kept each little tree,
Saved nested notes and kept them safe for you and me.
I hopped the board where races briefly stall,
Memo'd the canvas, and listened for the call.
A twitch, a hop—summary and menu, trimmed and tall. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main objective of the PR: fixing a board view crash caused by feature status lagging during race conditions, which is the central issue addressed by the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses a crash in the board view caused by race conditions and improves the handling of stale feature statuses. It also includes improvements to the specification parser. The changes involve removing duplicate cache invalidation, adding memoization to the KanbanBoard component, updating the board view row click handler, adding a menu item block in RowActions, and fixing the extractSummary() regex. The code changes look good and address the issues described in the pull request description.

Comment on lines +437 to +442
{!isCurrentAutoTask &&
isRunningTask &&
(feature.status === 'backlog' ||
feature.status === 'ready' ||
feature.status === 'interrupted' ||
feature.status === 'merge_conflict') && (
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The condition feature.status === 'backlog' || feature.status === 'ready' || feature.status === 'interrupted' || feature.status === 'merge_conflict' is repeated from board-view.tsx. Consider creating a shared helper function to avoid duplication and ensure consistency.

const isBacklogLike = (status: string) => {
  return status === 'backlog' || status === 'ready' || status === 'interrupted' || status === 'merge_conflict';
};

{!isCurrentAutoTask &&
  isRunningTask &&
  isBacklogLike(feature.status) && (

Comment on lines +217 to +218
// Use \n## [^#] to stop at same-level headers (## Foo) but NOT subsections (### Root Cause)
const sectionMatches = text.matchAll(/##\s*Summary\s*\n+([\s\S]*?)(?=\n## [^#]|\n\*\*|$)/gi);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comment is helpful in explaining the purpose of the regex, but it could be improved by clarifying why stopping at same-level headers is important for the summary extraction. Consider adding a brief explanation of the problem this solves.

Comment on lines +1911 to +1915
const isBacklogLike =
feature.status === 'backlog' ||
feature.status === 'merge_conflict' ||
feature.status === 'ready' ||
feature.status === 'interrupted';
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This isBacklogLike variable includes merge_conflict, ready, and interrupted statuses. It might be helpful to add a comment explaining why these statuses are considered 'backlog-like' in this context, especially since merge_conflict and interrupted might not be immediately obvious.

Comment on lines +434 to +436
{/* Running task with stale status (backlog/ready/interrupted but tracked as running).
These features are placed in the in_progress column by useBoardColumnFeatures
but their actual status hasn't updated yet, so no other menu block matches. */}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comment explains the purpose of this code block, but it could be improved by adding a link to the relevant code or a more specific reference to the function useBoardColumnFeatures to help future developers quickly understand the context.

Comment on lines +118 to +123
// NOTE: auto_mode_feature_start and auto_mode_feature_complete are NOT handled here
// for feature list reloading. That is handled by useAutoModeQueryInvalidation which
// invalidates the features.all query on those events. Duplicate invalidation here
// caused a re-render cascade through DndContext that triggered React error #185
// (maximum update depth exceeded), crashing the board view with an infinite spinner
// when a new feature was added and moved to in_progress.
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comment explains why auto_mode_feature_start is not handled here, but it could be improved by mentioning the specific code or hook that handles it (useAutoModeQueryInvalidation) to make it easier to trace the logic.

Address PR AutoMaker-Org#825 review feedback:
- Extract duplicated backlog-like status check into shared helper in constants.ts
- Improve spec-parser regex comment to clarify subsection preservation
- Add file path reference in row-actions.tsx comment for traceability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx (1)

435-469: Use the shared helper consistently in primary-action stale-running logic.

isBacklogLikeStatus is used here, but Lines 145-150 still hardcode the same status list in getPrimaryAction, which can drift.

♻️ Suggested consistency patch
-  if (
-    isRunningTask &&
-    (feature.status === 'backlog' ||
-      feature.status === 'merge_conflict' ||
-      feature.status === 'ready' ||
-      feature.status === 'interrupted') &&
-    handlers.onForceStop
-  ) {
+  if (isRunningTask && isBacklogLikeStatus(feature.status) && handlers.onForceStop) {
     return {
       icon: StopCircle,
       label: 'Stop',
       onClick: handlers.onForceStop,
       variant: 'destructive',
     };
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx`
around lines 435 - 469, getPrimaryAction contains a hardcoded list of
"backlog-like" statuses that duplicates the logic in isBacklogLikeStatus;
replace that duplicated status check inside getPrimaryAction with a call to
isBacklogLikeStatus(feature.status) so the primary-action stale-running branch
uses the shared helper consistently (update any conditional branches or guards
in getPrimaryAction that currently compare against the hardcoded statuses to
instead call isBacklogLikeStatus).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/server/src/services/spec-parser.ts`:
- Around line 219-224: The regex used to extract the "Summary" block in
spec-parser.ts (see variables sectionMatches, sectionMatch and getLastMatch) has
an overly broad lookahead (?=\n## [^#]|\n\*\*|$) that prematurely stops at bold
lines; remove the "\n\*\*" branch so the lookahead only ends on same-level "##"
headers or end-of-string (i.e., use (?=\n## [^#]|$)), then keep the existing
trimming/substring logic intact so bold markup inside the summary is preserved.

---

Nitpick comments:
In
`@apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx`:
- Around line 435-469: getPrimaryAction contains a hardcoded list of
"backlog-like" statuses that duplicates the logic in isBacklogLikeStatus;
replace that duplicated status check inside getPrimaryAction with a call to
isBacklogLikeStatus(feature.status) so the primary-action stale-running branch
uses the shared helper consistently (update any conditional branches or guards
in getPrimaryAction that currently compare against the hardcoded statuses to
instead call isBacklogLikeStatus).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c8787d and ab95f45.

📒 Files selected for processing (4)
  • apps/server/src/services/spec-parser.ts
  • apps/ui/src/components/views/board-view.tsx
  • apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx
  • apps/ui/src/components/views/board-view/constants.ts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/server/src/services/event-hook-service.ts (1)

598-604: Minor simplification: Extract common pathname assignment.

Both branches set url.pathname = '/board'. Consider moving it outside the conditional to reduce duplication.

♻️ Suggested simplification
       try {
         const url = new URL(clickUrl);
-        // Add featureId as query param for deep linking to board with feature output modal
-        if (context.featureId) {
-          url.pathname = '/board';
+        url.pathname = '/board';
+        if (context.featureId) {
           url.searchParams.set('featureId', context.featureId);
-        } else {
-          url.pathname = '/board';
         }
         clickUrl = url.toString();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/server/src/services/event-hook-service.ts` around lines 598 - 604, Move
the shared assignment url.pathname = '/board' out of the if/else to eliminate
duplication: always set url.pathname = '/board' first, then only run the
conditional body to call url.searchParams.set('featureId', context.featureId)
when context.featureId is truthy (leave out the else branch entirely). Update
the block that currently references context.featureId, url.pathname and
url.searchParams.set so pathname is assigned once and the conditional only
handles adding the featureId query param.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/server/src/services/event-hook-service.ts`:
- Around line 598-604: Move the shared assignment url.pathname = '/board' out of
the if/else to eliminate duplication: always set url.pathname = '/board' first,
then only run the conditional body to call url.searchParams.set('featureId',
context.featureId) when context.featureId is truthy (leave out the else branch
entirely). Update the block that currently references context.featureId,
url.pathname and url.searchParams.set so pathname is assigned once and the
conditional only handles adding the featureId query param.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13f2a7a and 0e4e9eb.

📒 Files selected for processing (2)
  • apps/server/src/services/event-hook-service.ts
  • apps/server/tests/unit/services/event-hook-service.test.ts

@gsxdsm gsxdsm merged commit b2915f4 into AutoMaker-Org:v1.0.0rc Mar 3, 2026
7 checks passed
gsxdsm added a commit that referenced this pull request Mar 3, 2026
Address PR #825 review feedback:
- Extract duplicated backlog-like status check into shared helper in constants.ts
- Improve spec-parser regex comment to clarify subsection preservation
- Add file path reference in row-actions.tsx comment for traceability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gsxdsm gsxdsm deleted the fix/board-crash-new-feat branch March 3, 2026 05:36
gsxdsm added a commit to gsxdsm/automaker that referenced this pull request Mar 3, 2026
Address PR AutoMaker-Org#825 review feedback:
- Extract duplicated backlog-like status check into shared helper in constants.ts
- Improve spec-parser regex comment to clarify subsection preservation
- Add file path reference in row-actions.tsx comment for traceability

Co-Authored-By: Claude Opus 4.6 <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.

1 participant