Skip to content

Bug: implement_task crashes on first implementation pass — no fork exists yet #194

Description

@ekuris-redhat

Bug

implement_task fails on the first implementation pass (before any PR is created) with two cascading errors:

  1. git fetch fork — "fatal: 'fork' does not appear to be a git repository"
  2. Cannot recreate workspace for <TICKET>: missing branch_name, current_repo, fork_owner, or fork_repo in state

If the workspace survives and the fetch error is bypassed, a second failure occurs after the container completes successfully:

  1. git push -u fork <branch> — "fatal: 'fork' does not appear to be a git repository"

Root cause

Commit 7ebb8b7 ("fix: persist review handoffs across workers", PR #168) added prepare_workspace() and push_to_fork_with_retry() calls to implement_task(). Both assume a fork remote already exists. On the first implementation pass the fork is not created until create_pull_request, so fork_owner, fork_repo, and the fork git remote are all absent.

Error flow

setup_workspace  →  creates workspace, clones repo, creates branch (no fork)
                     sets current_node = "implementation"
implement_bug_fix (= implement_task)
  ├─ prepare_workspace(state)
  │    ├─ workspace exists on disk → pull_rebase("fork") → FAILS (no fork remote)
  │    └─ fallback _recreate_workspace_from_fork() → FAILS (fork_owner/fork_repo empty)
  │
  └─ (if workspace survives) container runs successfully → push_to_fork_with_retry()
       └─ git push -u fork <branch> → FAILS (no fork remote)

Affected paths

  • Bug workflow: plan_approval → decompose_plan → setup_workspace → implement_bug_fix
  • Feature workflow: task_approval → setup_workspace → implement_task

Any first-pass implementation where no PR has been created yet.

Post-PR paths are NOT affected

implement_review and attempt_ci_fix run after create_pull_request, so fork_owner/fork_repo are always populated.

Fix

Two changes needed in the first-pass path:

1. src/forge/workflow/nodes/workspace_setup.pyprepare_workspace()

When the workspace exists on disk but no fork info is available, skip the sync and return the existing workspace:

if workspace_path and Path(workspace_path).exists():
    workspace = Workspace(...)
    git = GitOperations(workspace)

    if not fork_owner or not fork_repo:
        return workspace_path, git

    try:
        git.pull_rebase(remote=remote)
    ...

2. src/forge/workflow/nodes/implementation.pyimplement_task()

Guard both push_to_fork_with_retry() call sites so they only push when a fork exists:

has_fork = bool(state.get("fork_owner") and state.get("fork_repo"))

# "all tasks done" path
if has_fork:
    await push_to_fork_with_retry(git)

# "per-task commit" path
if has_fork:
    await push_to_fork_with_retry(git)

Reproduction

  1. Create a bug ticket with forge:managed label
  2. Let Forge generate RCA and plan
  3. Approve the plan (set forge:plan-approved)
  4. Worker reaches implement_bug_fix → crashes with the fork error

Versions

Introduced in commit 7ebb8b7 (PR #168), present on current main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions