Skip to content

Conversation

@ketkarameya
Copy link

Benchmark PR for Gitar evaluation

Original PR: agentic-review-benchmarks#13

fix: workflow incorrectly marked as completed while nodes are still executing

Comment on lines 83 to +86
for edge in outgoing_edges:
self._state_manager.mark_edge_skipped(edge.id)
# Recursively propagate skip
self.propagate_skip_from_edge(edge.id)
self._state_manager.mark_edge_skipped(edge.id)

Choose a reason for hiding this comment

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

🚨 Bug: Edge marked as skipped AFTER propagation breaks recursion

The reordering of mark_edge_skipped() to occur AFTER propagate_skip_from_edge() breaks the recursive skip propagation entirely.

How it fails:

  1. _propagate_skip_to_node("A") is called for a skipped node A
  2. For each outgoing edge from A, propagate_skip_from_edge(edge.id) is called BEFORE mark_edge_skipped(edge.id)
  3. Inside propagate_skip_from_edge, it calls analyze_edge_states(incoming_edges) on the downstream node
  4. Since the edge has NOT been marked as skipped yet (still UNKNOWN), analyze_edge_states returns has_unknown=True
  5. The method returns immediately without propagating — the skip chain is broken

Evidence from the same file: The skip_branch_paths() method (line 95-97) correctly marks the edge as skipped BEFORE calling propagate_skip_from_edge(). The original order in _propagate_skip_to_node was also correct (mark first, then propagate).

Impact: Skip states will not propagate beyond the first level of outgoing edges. Downstream nodes that should be skipped will remain in UNKNOWN state, potentially causing the workflow to hang waiting for nodes that will never execute.

Was this helpful? React with 👍 / 👎

Suggested change
for edge in outgoing_edges:
self._state_manager.mark_edge_skipped(edge.id)
# Recursively propagate skip
self.propagate_skip_from_edge(edge.id)
self._state_manager.mark_edge_skipped(edge.id)
for edge in outgoing_edges:
self._state_manager.mark_edge_skipped(edge.id)
# Recursively propagate skip
self.propagate_skip_from_edge(edge.id)
  • Apply suggested fix

if edge_states["has_taken"]:
# Enqueue node
# Start execution and enqueue node
print(f"Starting execution for node: {downstream_node_id}")

Choose a reason for hiding this comment

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

⚠️ Quality: Debug print() statement left in production code

A print(f"Starting execution for node: {downstream_node_id}") statement is left in production workflow execution code. This will write to stdout on every workflow node execution where skip propagation triggers the "has_taken" path.

Impact:

  • Pollutes application logs/stdout in production
  • In containerized/serverless environments, this adds noise to structured logging
  • Performance overhead from string formatting on every invocation (minor but unnecessary)

This should either be removed or replaced with proper logging using the logging module at DEBUG level.

Was this helpful? React with 👍 / 👎

Suggested change
print(f"Starting execution for node: {downstream_node_id}")
# Start execution and enqueue node
self._state_manager.start_execution(downstream_node_id)
  • Apply suggested fix

Copy link

@gitar-bot-staging gitar-bot-staging bot left a comment

Choose a reason for hiding this comment

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

⚠️ This PR is blocked due to unresolved code review findings.

Configure merge blocking · Maintainers can dismiss this review. Gitar never approves changes.

@gitar-bot-staging
Copy link

gitar-bot-staging bot commented Feb 10, 2026

Code Review 🚫 Blocked 0 resolved / 3 findings

The start_execution() fix is correct and addresses the premature-completion bug, but the edge marking reorder in _propagate_skip_to_node introduces a critical regression: edges are marked as skipped AFTER recursive propagation, causing analyze_edge_states to see them as UNKNOWN and halt propagation. Also, a debug print() statement was left in production code.

🚨 Bug: Edge marked as skipped AFTER propagation breaks recursion

📄 api/core/workflow/graph_engine/graph_traversal/skip_propagator.py:83-86

The reordering of mark_edge_skipped() to occur AFTER propagate_skip_from_edge() breaks the recursive skip propagation entirely.

How it fails:

  1. _propagate_skip_to_node("A") is called for a skipped node A
  2. For each outgoing edge from A, propagate_skip_from_edge(edge.id) is called BEFORE mark_edge_skipped(edge.id)
  3. Inside propagate_skip_from_edge, it calls analyze_edge_states(incoming_edges) on the downstream node
  4. Since the edge has NOT been marked as skipped yet (still UNKNOWN), analyze_edge_states returns has_unknown=True
  5. The method returns immediately without propagating — the skip chain is broken

Evidence from the same file: The skip_branch_paths() method (line 95-97) correctly marks the edge as skipped BEFORE calling propagate_skip_from_edge(). The original order in _propagate_skip_to_node was also correct (mark first, then propagate).

Impact: Skip states will not propagate beyond the first level of outgoing edges. Downstream nodes that should be skipped will remain in UNKNOWN state, potentially causing the workflow to hang waiting for nodes that will never execute.

Suggested fix
        for edge in outgoing_edges:
            self._state_manager.mark_edge_skipped(edge.id)
            # Recursively propagate skip
            self.propagate_skip_from_edge(edge.id)
⚠️ Quality: Debug print() statement left in production code

📄 api/core/workflow/graph_engine/graph_traversal/skip_propagator.py:62

A print(f"Starting execution for node: {downstream_node_id}") statement is left in production workflow execution code. This will write to stdout on every workflow node execution where skip propagation triggers the "has_taken" path.

Impact:

  • Pollutes application logs/stdout in production
  • In containerized/serverless environments, this adds noise to structured logging
  • Performance overhead from string formatting on every invocation (minor but unnecessary)

This should either be removed or replaced with proper logging using the logging module at DEBUG level.

Suggested fix
            # Start execution and enqueue node
            self._state_manager.start_execution(downstream_node_id)
💡 Quality: Test doesn't verify start_execution is called before enqueue_node

📄 api/tests/unit_tests/core/workflow/graph_engine/graph_traversal/test_skip_propagator.py:78-80

The test test_propagate_skip_from_edge_with_taken_edge_enqueues_node verifies that both start_execution and enqueue_node are called, but doesn't verify the ordering. Since the whole point of this PR is to ensure start_execution() happens before enqueue_node() (to prevent premature workflow completion), the test should assert the call order.

You can use mock.assert_has_calls([call.start_execution("node_2"), call.enqueue_node("node_2")]) or check mock_state_manager.mock_calls to verify ordering.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

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.

2 participants