Skip to content

fix: verify conflict markers removed after AI cherry-pick resolution #1137

Description

@rnetser

Problem

After AI conflict resolution during cherry-pick, the code proceeds to git add -A + cherry-pick --continue without verifying that conflict markers were actually removed from files. If the AI fails silently (e.g. sidecar returns success=True but the model never ran), unresolved conflict markers get committed.

Root Cause

In _resolve_cherry_pick_with_ai() (webhook_server/libs/handlers/runner_handler.py), the only validation after the AI call is:

if not ai_call_result.success:
    ...
    return False, ""

The pi_sidecar_client marks results as success=True based on HTTP 200 status, regardless of whether the AI actually performed any work. The AI resolves conflicts through tool calls (edit/write), not through its response text — so empty text alone is not an indicator of failure. However, when the model is never invoked (0 tokens in/out), no tool calls happen and conflict markers remain in the files.

Failure Flow

1. /cherry-pick <branch> → git cherry-pick → CONFLICT in file.py
2. AI conflict resolution invoked
3. Sidecar returns success=True but model never ran (0 tokens)
4. No tool calls executed → conflict markers still in files
         ↓
5. git add -A              ← stages files with conflict markers
6. cherry-pick --continue  ← commits broken file
7. Pre-commit fails: SyntaxError (conflict markers)
8. Cherry-pick aborts via "unfixable errors" path

Pre-commit acts as a safety net, but the cherry-pick falls through to the wrong error path ("unfixable errors") instead of the proper manual cherry-pick fallback with instructions.

Expected Flow

1–4. Same as above
         ↓
5. Scan working tree for conflict markers (<<<<<<< / ======= / >>>>>>>)
6. Markers found → return (False, "") → manual fallback with instructions

Proposed Fix

After the AI call succeeds but before git add -A, scan the conflicted files for remaining conflict markers (<<<<<<<, =======, >>>>>>>). If any remain, treat the resolution as failed and fall back to the manual cherry-pick path.

Done

  • Add conflict marker check after AI resolution in _resolve_cherry_pick_with_ai()
  • Add test covering unresolved conflict markers after AI call

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions