Skip to content

Conversation

@elmateo487
Copy link

@elmateo487 elmateo487 commented Jan 22, 2026

Summary

This PR fixes two related bugs where tasks incorrectly show "Needs Resume" or get stuck in human_review status:

Fix 1: Planning crash leaves task in human_review (#1149)

When planning crashes and leaves no phases/subtasks, update_status_from_subtasks() was preserving the human_review status even though there was no valid plan. This caused tasks to show "Incomplete + Needs Resume" in the UI with 0 subtasks.

Solution: Check if status is human_review but phases list is empty - this indicates planning failed. Reset to backlog with a recovery note instead.

File: apps/backend/implementation_plan/plan.py

Fix 2: Task stuck in human_review after approval (#509)

After a user approves a plan, clicking "Resume" would not start execution because there was no code to transition the status from human_review to in_progress when continuing a build. The task would remain stuck forever.

Solution: In the "continuing build" path of coder.py, check if the plan is in human_review status and if so, validate the approval and transition to in_progress before starting execution.

File: apps/backend/agents/coder.py

Test plan

  • Create a task and interrupt planning phase mid-way - verify task goes to Backlog (not Human Review)
  • Create and approve a plan, then resume - verify execution starts (not stuck in Human Review)
  • Normal flow still works: plan → approve → execute → complete

Related Issues

Fixes #1149
Fixes #509
Related to #457, #585

Summary by CodeRabbit

  • Bug Fixes
    • Build resumption now verifies approval before continuing; invalid approvals require re-approval.
    • Planning can recover from a stuck/crashed state by resetting affected plans back to backlog.
    • When a task fails with no subtasks, status now resets to backlog (with a warning) instead of moving to human review.

✏️ Tip: You can customize this high-level summary in your review settings.

This PR fixes two related bugs where tasks incorrectly show "Needs Resume"
or get stuck in human_review status:

## Fix 1: Planning crash leaves task in human_review (AndyMik90#1149)

When planning crashes and leaves no phases/subtasks, `update_status_from_subtasks()`
was preserving the human_review status even though there was no valid plan.
This caused tasks to show "Incomplete + Needs Resume" in the UI.

**Solution:** Check if status is human_review but phases list is empty - this
indicates planning failed. Reset to backlog with a recovery note instead.

## Fix 2: Task stuck in human_review after approval (AndyMik90#509)

After a user approves a plan, clicking "Resume" would not start execution
because there was no code to transition the status from human_review to
in_progress when continuing a build.

**Solution:** In the "continuing build" path of coder.py, check if the plan
is in human_review status and if so, validate the approval and transition
to in_progress before starting execution.
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Matthew Larson seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @elmateo487, 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 resolves two critical bugs related to task status management, specifically addressing scenarios where tasks would incorrectly remain in "human_review" or display misleading statuses. The changes enhance the robustness of the task workflow by ensuring proper state transitions after planning failures and user approvals, leading to a more reliable and predictable user experience.

Highlights

  • Planning Crash Recovery: Implemented a mechanism to detect and recover from planning crashes that leave tasks in an invalid "human_review" state without any subtasks. Tasks are now correctly reset to "backlog" with a recovery note.
  • Post-Approval Execution Flow: Ensured that tasks in "human_review" status correctly transition to "in_progress" and resume execution after a valid user approval, preventing them from getting stuck.
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 Jan 22, 2026

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

The changes restore correct plan state transitions: recover tasks left in human_review with no phases/subtasks (reset to backlog), and on build resume, detect approved review state to transition plans from human_review/review to in_progress so execution can continue.

Changes

Cohort / File(s) Summary
Build resume / approval check
apps/backend/agents/coder.py
On resuming a build, load the implementation plan and ReviewState; if plan is human_review/review and the review shows approved, update plan status and planStatus to in_progress, persist implementation_plan.json, otherwise warn and return without starting execution.
Plan status recovery on empty plan
apps/backend/implementation_plan/plan.py
In update_status_from_subtasks(), add a special-case when there are no subtasks and no phases while status is human_review/review: reset statusbacklog, planStatuspending, and set a recoveryNote to avoid preserving an invalid human_review state.
Frontend failure-path status reset
apps/frontend/src/main/ipc-handlers/agent-events-handlers.ts
On agent failure, if the task has no subtasks, reset status to backlog and log a warning instead of moving the task into human_review; preserve existing human_review behavior when subtasks exist.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as Agent (coder)
    participant FS as FileSystem (implementation_plan.json, review_state.json)
    participant Plan as ImplementationPlan
    participant Frontend as Frontend / IPC

    Agent->>FS: load implementation_plan.json
    Agent->>Plan: parse plan (status, planStatus, phases)
    alt plan.status == "human_review" and plan.planStatus == "review"
        Agent->>FS: load review_state.json
        alt review.approved == true
            Agent->>Plan: set status/planStatus -> "in_progress"
            Agent->>FS: save implementation_plan.json
            Agent->>Frontend: emit build/resume start
            Frontend->>Agent: begin execution / dispatch subtasks
        else review not approved
            Agent->>Frontend: warn "re-approval required", abort resume
        end
    else
        Agent->>Frontend: continue resume or start as normal
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug, area/backend, area/frontend, size/S

Suggested reviewers

  • AndyMik90
  • MikeeBuilds

Poem

🐇 I nudge a plan from stuck to go,
Hopped through files where edge-cases grow.
If reviews are green, I start the run—
If plans are empty, back to backlog fun.
Hooray, small fixes, carrot-powered one!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly references the specific bugs (#1149, #509) being fixed and accurately describes the primary objective of correcting human_review status issues.
Linked Issues check ✅ Passed The PR addresses both linked issues: Fix 1 handles #1149 by resetting human_review to backlog when planning crashes with no phases; Fix 2 handles #509 by transitioning human_review to in_progress on approved plan execution.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to fixing the two linked issues; no extraneous modifications were introduced beyond the stated objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

🎉 Thanks for your first PR!

A maintainer will review it soon. Please make sure:

  • Your branch is synced with develop
  • CI checks pass
  • You've followed our contribution guide

Welcome to the Auto Claude community!

@sentry
Copy link

sentry bot commented Jan 22, 2026

Codecov Report

❌ Patch coverage is 0% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
apps/backend/agents/coder.py 0.00% 12 Missing ⚠️
apps/backend/implementation_plan/plan.py 0.00% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

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 two important bugs that cause tasks to get stuck in the human_review status. The fix in implementation_plan/plan.py for handling planning crashes is well-implemented. However, the change in apps/backend/agents/coder.py introduces a critical bug. It incorrectly handles the ImplementationPlan, treating a dictionary as an object, which would lead to a runtime error. I've provided a detailed comment with a code suggestion to correct this issue.

Comment on lines +195 to +209
plan = load_implementation_plan(spec_dir)
if plan and plan.status == "human_review" and plan.planStatus == "review":
from review.state import ReviewState
review_state = ReviewState.load(spec_dir)
if review_state.is_approval_valid(spec_dir):
# User approved the plan - transition to in_progress now that execution begins
plan.status = "in_progress"
plan.planStatus = "in_progress"
plan_file = spec_dir / "implementation_plan.json"
plan.save(plan_file)
print_status("Transitioned from human_review to in_progress after approval", "success")
else:
# Plan changed after approval or not approved - stay in human_review
print_status("Plan requires re-approval before execution can continue", "warning")
return
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This block has a bug: load_implementation_plan from agents.utils returns a dictionary, but the code attempts to access attributes (.status) and methods (.save()) as if plan were an object. This will raise an AttributeError and cause a crash.

The logic should be updated to correctly load an ImplementationPlan object instance to allow for attribute access and use of the .save() method.

Suggested change
plan = load_implementation_plan(spec_dir)
if plan and plan.status == "human_review" and plan.planStatus == "review":
from review.state import ReviewState
review_state = ReviewState.load(spec_dir)
if review_state.is_approval_valid(spec_dir):
# User approved the plan - transition to in_progress now that execution begins
plan.status = "in_progress"
plan.planStatus = "in_progress"
plan_file = spec_dir / "implementation_plan.json"
plan.save(plan_file)
print_status("Transitioned from human_review to in_progress after approval", "success")
else:
# Plan changed after approval or not approved - stay in human_review
print_status("Plan requires re-approval before execution can continue", "warning")
return
from implementation_plan.plan import ImplementationPlan
plan_file = spec_dir / "implementation_plan.json"
if plan_file.exists():
plan = ImplementationPlan.load(plan_file)
if plan.status == "human_review" and plan.planStatus == "review":
from review.state import ReviewState
review_state = ReviewState.load(spec_dir)
if review_state.is_approval_valid(spec_dir):
# User approved the plan - transition to in_progress now that execution begins
plan.status = "in_progress"
plan.planStatus = "in_progress"
plan.save(plan_file)
print_status("Transitioned from human_review to in_progress after approval", "success")
else:
# Plan changed after approval or not approved - stay in human_review
print_status("Plan requires re-approval before execution can continue", "warning")
return

Comment on lines +195 to +204
plan = load_implementation_plan(spec_dir)
if plan and plan.status == "human_review" and plan.planStatus == "review":
from review.state import ReviewState
review_state = ReviewState.load(spec_dir)
if review_state.is_approval_valid(spec_dir):
# User approved the plan - transition to in_progress now that execution begins
plan.status = "in_progress"
plan.planStatus = "in_progress"
plan_file = spec_dir / "implementation_plan.json"
plan.save(plan_file)

This comment was marked as outdated.

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: 3

🤖 Fix all issues with AI agents
In `@apps/backend/agents/coder.py`:
- Around line 195-205: The transition to in_progress is being overwritten
because ImplementationPlan.save() calls update_status_from_subtasks() which
recomputes status; modify the flow so the explicit in_progress transition
persists: either add a save(preserve_status=True) (or a
persist_without_recompute()/write_raw(path)) to ImplementationPlan and call that
here after setting plan.status and plan.planStatus, or update
ImplementationPlan.save to accept an option to skip update_status_from_subtasks;
then use that new API in the block that handles approval (the code that calls
load_implementation_plan, ReviewState.load, review_state.is_approval_valid) so
the in_progress value is written to disk without being recomputed away.

In `@apps/backend/implementation_plan/plan.py`:
- Around line 170-178: Run the Python formatter (ruff format) on the
implementation plan module to fix CI formatting failures: apply ruff format to
the file containing the code that checks self.status == "human_review" and
self.phases (the block that sets self.status, self.planStatus, and
self.recoveryNote), re-stage the reformatted
apps/backend/implementation_plan/plan.py, and re-commit so the CI ruff check
passes.
- Around line 170-178: The current check only resets when self.status ==
"human_review" and not self.phases, which misses cases where phases exist but
contain zero subtasks; update the condition in the same block (where
self.status, self.planStatus, and self.recoveryNote are set) to detect "no
subtasks" by verifying that none of the phases have subtasks (e.g.,
replace/not-only-check self.phases with a test like "no phase in self.phases has
subtasks" or using any()/all() over phase.subtasks) and then perform the same
reset to backlog, planStatus="pending" and set recoveryNote.

Comment on lines +195 to +205
plan = load_implementation_plan(spec_dir)
if plan and plan.status == "human_review" and plan.planStatus == "review":
from review.state import ReviewState
review_state = ReviewState.load(spec_dir)
if review_state.is_approval_valid(spec_dir):
# User approved the plan - transition to in_progress now that execution begins
plan.status = "in_progress"
plan.planStatus = "in_progress"
plan_file = spec_dir / "implementation_plan.json"
plan.save(plan_file)
print_status("Transitioned from human_review to in_progress after approval", "success")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

plan.save() recomputes status and can undo the in_progress transition.

ImplementationPlan.save() calls update_status_from_subtasks(), which sets backlog/pending when all subtasks are still pending (common right after approval). That means this transition likely won’t persist to disk. Consider preserving explicit in_progress in the “all pending” branch or persisting without recomputing status.

🐛 One possible fix (apps/backend/implementation_plan/plan.py)
-            if self.status == "human_review" and self.planStatus == "review":
-                pass
-            else:
-                self.status = "backlog"
-                self.planStatus = "pending"
+            if self.status == "human_review" and self.planStatus == "review":
+                pass
+            elif self.status == "in_progress" and self.planStatus == "in_progress":
+                # Preserve explicit transition after approval
+                pass
+            else:
+                self.status = "backlog"
+                self.planStatus = "pending"
🧰 Tools
🪛 GitHub Actions: Lint

[error] 195-195: Ruff format check detected formatting changes. 2 files would be reformatted. Run 'ruff format' to fix formatting.

🤖 Prompt for AI Agents
In `@apps/backend/agents/coder.py` around lines 195 - 205, The transition to
in_progress is being overwritten because ImplementationPlan.save() calls
update_status_from_subtasks() which recomputes status; modify the flow so the
explicit in_progress transition persists: either add a
save(preserve_status=True) (or a persist_without_recompute()/write_raw(path)) to
ImplementationPlan and call that here after setting plan.status and
plan.planStatus, or update ImplementationPlan.save to accept an option to skip
update_status_from_subtasks; then use that new API in the block that handles
approval (the code that calls load_implementation_plan, ReviewState.load,
review_state.is_approval_valid) so the in_progress value is written to disk
without being recomputed away.

Comment on lines +170 to +178
# No subtasks yet - check if this is a failed planning state
# Fix for #1149: If status is human_review but no phases/subtasks exist,
# planning crashed - reset to backlog instead of preserving invalid state
if self.status == "human_review" and not self.phases:
# Planning failed - don't show as human_review with Resume button
self.status = "backlog"
self.planStatus = "pending"
self.recoveryNote = "Planning phase failed - no implementation plan created"
return
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Ruff format is failing for this file.

CI indicates ruff format would reformat this file. Please run ruff format and re-commit.

🧰 Tools
🪛 GitHub Actions: Lint

[error] 174-174: Ruff format check detected formatting changes. Run 'ruff format' to fix formatting.

🤖 Prompt for AI Agents
In `@apps/backend/implementation_plan/plan.py` around lines 170 - 178, Run the
Python formatter (ruff format) on the implementation plan module to fix CI
formatting failures: apply ruff format to the file containing the code that
checks self.status == "human_review" and self.phases (the block that sets
self.status, self.planStatus, and self.recoveryNote), re-stage the reformatted
apps/backend/implementation_plan/plan.py, and re-commit so the CI ruff check
passes.

⚠️ Potential issue | 🟠 Major

Broaden the failed-planning reset to cover empty phases with zero subtasks.

In this not all_subtasks branch, gating on not self.phases misses cases where phases exist but are empty (partial/crashed write). That still leaves human_review stuck with no actionable subtasks. Consider treating any human_review + no subtasks as a failed plan here.

🐛 Proposed fix
-            if self.status == "human_review" and not self.phases:
+            if self.status == "human_review":
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# No subtasks yet - check if this is a failed planning state
# Fix for #1149: If status is human_review but no phases/subtasks exist,
# planning crashed - reset to backlog instead of preserving invalid state
if self.status == "human_review" and not self.phases:
# Planning failed - don't show as human_review with Resume button
self.status = "backlog"
self.planStatus = "pending"
self.recoveryNote = "Planning phase failed - no implementation plan created"
return
# No subtasks yet - check if this is a failed planning state
# Fix for `#1149`: If status is human_review but no phases/subtasks exist,
# planning crashed - reset to backlog instead of preserving invalid state
if self.status == "human_review":
# Planning failed - don't show as human_review with Resume button
self.status = "backlog"
self.planStatus = "pending"
self.recoveryNote = "Planning phase failed - no implementation plan created"
return
🧰 Tools
🪛 GitHub Actions: Lint

[error] 174-174: Ruff format check detected formatting changes. Run 'ruff format' to fix formatting.

🤖 Prompt for AI Agents
In `@apps/backend/implementation_plan/plan.py` around lines 170 - 178, The current
check only resets when self.status == "human_review" and not self.phases, which
misses cases where phases exist but contain zero subtasks; update the condition
in the same block (where self.status, self.planStatus, and self.recoveryNote are
set) to detect "no subtasks" by verifying that none of the phases have subtasks
(e.g., replace/not-only-check self.phases with a test like "no phase in
self.phases has subtasks" or using any()/all() over phase.subtasks) and then
perform the same reset to backlog, planStatus="pending" and set recoveryNote.

When the planning agent exits with a non-zero code (crash/failure), the exit
handler was unconditionally setting status to human_review. This caused tasks
to show "Needs Resume" even when planning hadn't created any phases/subtasks.

The fix adds the same subtask check that exists for successful exits (code=0)
to the failure branch. If no subtasks exist when planning fails, the task is
reset to backlog so the user can retry, rather than being stuck in human_review.

Fixes AndyMik90#1149, AndyMik90#509
@elmateo487 elmateo487 closed this Jan 22, 2026
@elmateo487 elmateo487 deleted the fix/human-review-status-bugs branch January 22, 2026 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants