Skip to content

fix(executor): handle Response block format in workflow executor tool#3532

Open
waleedlatif1 wants to merge 2 commits intostagingfrom
fix/executor
Open

fix(executor): handle Response block format in workflow executor tool#3532
waleedlatif1 wants to merge 2 commits intostagingfrom
fix/executor

Conversation

@waleedlatif1
Copy link
Collaborator

@waleedlatif1 waleedlatif1 commented Mar 12, 2026

Summary

  • When a child workflow has a Response block, the execute endpoint returns the block's data directly (e.g., {"issues": []}) without the standard {success, executionId, output} wrapper
  • The transformResponse in the workflow executor tool was defaulting success to false via data?.success ?? false, causing every agent tool call to a Response-block workflow to report "Tool execution failed" — even when the workflow completed successfully
  • Fix detects the response format by checking for executionId (string) + success (boolean), and falls back to response.ok for Response block responses

Test plan

  • 7 new unit tests covering: standard format success/failure, Response block format, user data with success field, empty data, array data, and error field preservation
  • All 27 tests pass (bunx vitest run tools/workflow/executor.test.ts)
  • Verified no regression: standard format produces identical output to old code
  • Manual: create a workflow with a Response block, call it from an Agent block, confirm it no longer returns "Tool execution failed"

When a child workflow has a Response block, the execute endpoint returns
the block's data directly without the standard {success, executionId, output}
wrapper. The transformResponse was defaulting success to false, causing
"Tool execution failed" errors even when the workflow completed successfully.

Detect the response format by checking for executionId + success boolean,
and fall back to response.ok for Response block responses.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@cursor
Copy link

cursor bot commented Mar 12, 2026

PR Summary

Medium Risk
Changes response parsing for workflow execution results; incorrect format detection could mask failures or mis-shape outputs, but behavior is covered by new unit tests.

Overview
Fixes workflowExecutorTool.transformResponse to handle two execute endpoint response shapes: the standard { success, executionId, output, metadata } wrapper and raw Response block payloads.

The parser now detects the standard wrapper via success + executionId, otherwise treats the JSON body as the tool output and derives success from response.ok (avoiding false “tool execution failed” reports). Adds focused unit tests covering both formats and edge cases (arrays/empty bodies, user payloads containing success, and error-field preservation).

Written by Cursor Bugbot for commit a8504f7. Configure here.

@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 12, 2026 7:17am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR fixes a bug in the workflow executor tool's transformResponse where child workflows that use a Response block (returning arbitrary user data without the standard { success, executionId, output } envelope) were always reported as failures due to data?.success ?? false defaulting to false.

The fix introduces a two-format detection heuristic in apps/sim/tools/workflow/executor.ts: if the response body contains both a boolean success field and a string executionId field it is treated as the standard envelope format; otherwise it is treated as a raw Response-block payload and response.ok is used for the success flag.

Key changes:

  • transformResponse now distinguishes between standard format ({ success, executionId, output, error, metadata }) and Response-block format (arbitrary user data) using isStandardFormat detection
  • The detection heuristic has a documented edge case: user data that coincidentally contains both a boolean success and a string executionId field will be misidentified as standard format, causing the actual payload to be silently replaced with data.output ?? {}
  • 7 new unit tests added covering all primary branches of the new logic

Confidence Score: 3/5

  • Safe to merge for the described bug fix, but the format detection heuristic has a potential silent data-loss edge case worth addressing.
  • The fix correctly resolves the reported bug and is backed by good test coverage. However, the isStandardFormat heuristic can false-positive on user payloads that happen to include both success: boolean and executionId: string, silently returning {} as the output instead of the actual data — a regression for those users. Additionally, childWorkflowId/childWorkflowName are read from the raw user payload in the Response-block path, which could produce incorrect metadata values.
  • apps/sim/tools/workflow/executor.ts — specifically the isStandardFormat detection logic and the childWorkflowId/childWorkflowName fields in the Response-block path.

Important Files Changed

Filename Overview
apps/sim/tools/workflow/executor.ts Core fix for Response-block format handling; detection heuristic has a false-positive edge case if user data contains both a boolean success and string executionId field, causing silent data loss.
apps/sim/tools/workflow/executor.test.ts 7 new well-structured unit tests cover standard format success/failure, Response-block format, empty/array data, and error field propagation; no issues found.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[transformResponse called] --> B[await response.json to get data]
    B --> C{success is boolean AND executionId is string?}
    C -- Yes --> D[isStandardFormat = true]
    C -- No --> E[isStandardFormat = false]
    D --> F[outputData = data.output or empty obj]
    D --> G[success = data.success]
    D --> H[duration = data.metadata.duration or 0]
    E --> I[outputData = data]
    E --> J[success = response.ok]
    E --> K[duration = 0]
    F --> L[Return result object]
    I --> L
    G --> L
    J --> L
    H --> L
    K --> L
    L --> M[success, duration, childWorkflowId, childWorkflowName, output, result, error]
Loading

Last reviewed commit: a8504f7

Comment on lines +61 to +62
const isStandardFormat =
typeof data?.success === 'boolean' && typeof data?.executionId === 'string'
Copy link
Contributor

Choose a reason for hiding this comment

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

False-positive format detection for user data with executionId field

The heuristic typeof data?.success === 'boolean' && typeof data?.executionId === 'string' will misidentify a user-defined Response block payload that happens to include both a boolean success field and a string executionId field (e.g., a workflow that re-wraps or forwards another workflow's output, or a workflow querying the executions API and returning raw rows).

When misidentified as standard format, data.output ?? {} is returned as outputData — but user payloads normally have no output key, so the caller silently receives an empty object {} instead of the actual response data, without any error.

Consider adding a third discriminator that is effectively impossible to appear in arbitrary user data. For example, requiring data?.metadata !== undefined (always present in the standard envelope) alongside executionId:

Suggested change
const isStandardFormat =
typeof data?.success === 'boolean' && typeof data?.executionId === 'string'
const isStandardFormat =
typeof data?.success === 'boolean' &&
typeof data?.executionId === 'string' &&
data?.metadata !== undefined

Or document this known limitation clearly in a code comment so future maintainers understand the trade-off.

Comment on lines 70 to 71
childWorkflowId: data?.workflowId ?? '',
childWorkflowName: data?.workflowName ?? '',
Copy link
Contributor

Choose a reason for hiding this comment

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

childWorkflowId/childWorkflowName read from arbitrary user payload

In the Response-block format path, data is the raw user-defined payload (e.g., { issues: [], total: 0 }). Reading data?.workflowId and data?.workflowName from this payload will always fall back to '' for typical user data — but if a user's workflow intentionally returns an object with a workflowId or workflowName field (e.g., a workflow that queries workflow metadata), those user-defined values will be incorrectly surfaced as child-workflow metadata in the result.

Consider defaulting these fields to '' unconditionally for the Response-block path:

Suggested change
childWorkflowId: data?.workflowId ?? '',
childWorkflowName: data?.workflowName ?? '',
childWorkflowId: isStandardFormat ? (data?.workflowId ?? '') : '',
childWorkflowName: isStandardFormat ? (data?.workflowName ?? '') : '',

- Add UUID validation on executionId to eliminate false-positive detection
  when user Response block data coincidentally contains success + executionId
- Scope childWorkflowId/childWorkflowName to standard format only so user
  payload fields don't leak into child workflow metadata
- Add test coverage for both edge cases

Co-Authored-By: Claude Opus 4.6 <[email protected]>
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