-
Notifications
You must be signed in to change notification settings - Fork 50.8k
feat(core): Switch to structured destination node (no-changelog) #22143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
BundleMonUnchanged files (2)
No change in files bundle size Groups updated (2)
Final result: ✅ View report in BundleMon website ➡️ |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This comment has been minimized.
This comment has been minimized.
|
E2E Tests: n8n tests passed after 9m 1.7s Run Details
Groups
This message was posted automatically by
currents.dev | Integration Settings
|
packages/@n8n/task-runner/src/js-task-runner/__tests__/js-task-runner.test.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cubic analysis
1 issue found across 25 files
Prompt for AI agents (all 1 issues)
Understand the root cause of the following 1 issues and fix them.
<file name="packages/cli/src/workflows/workflow-execution.service.ts">
<violation number="1" location="packages/cli/src/workflows/workflow-execution.service.ts:104">
Rule violated: **Tests**
Manual execution behavior is being rewritten to pass a structured destination node so that partial runs (per Linear issue CAT-1265) only execute the intended nodes, yet the PR adds no unit/workflow tests to demonstrate that this bug is fixed. The Community PR Guidelines explicitly require PRs to include tests, so this regression fix currently ships without the mandated coverage and risks the issue recurring.</violation>
</file>
Linked issue analysis
Linked issue: CAT-1265: Bug - Form node - executing previous nodes causes current node to run
| Status | Acceptance criteria | Notes |
|---|---|---|
| Executing previous nodes should not run the current node when in a 'next form step' node | Added destination.mode & conditional include, but callers still default to inclusive |
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| ) { | ||
| const { workflowData, startNodes, dirtyNodeNames, triggerToStartFrom, agentRequest } = payload; | ||
| let { runData } = payload; | ||
| const destinationNode: IDestinationNode | undefined = payload.destinationNode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rule violated: Tests
Manual execution behavior is being rewritten to pass a structured destination node so that partial runs (per Linear issue CAT-1265) only execute the intended nodes, yet the PR adds no unit/workflow tests to demonstrate that this bug is fixed. The Community PR Guidelines explicitly require PRs to include tests, so this regression fix currently ships without the mandated coverage and risks the issue recurring.
Prompt for AI agents
Address the following comment on packages/cli/src/workflows/workflow-execution.service.ts at line 104:
<comment>Manual execution behavior is being rewritten to pass a structured destination node so that partial runs (per Linear issue CAT-1265) only execute the intended nodes, yet the PR adds no unit/workflow tests to demonstrate that this bug is fixed. The Community PR Guidelines explicitly require PRs to include tests, so this regression fix currently ships without the mandated coverage and risks the issue recurring.</comment>
<file context>
@@ -92,26 +93,26 @@ export class WorkflowExecutionService {
) {
+ const { workflowData, startNodes, dirtyNodeNames, triggerToStartFrom, agentRequest } = payload;
+ let { runData } = payload;
+ const destinationNode: IDestinationNode | undefined = payload.destinationNode
+ ? {
+ nodeName: payload.destinationNode,
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR intentionally does not fix the e2e behaviour. A subsequent PR will update the API, as well as add tests to verify that the mode is handled appropriately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 29 files
Prompt for AI agents (all 3 issues)
Understand the root cause of the following 3 issues and fix them.
<file name="packages/cli/src/events/relays/telemetry.event-relay.ts">
<violation number="1" location="packages/cli/src/events/relays/telemetry.event-relay.ts:790">
Remove the stray `console.log`—it dumps manual execution data (potentially sensitive) to stdout instead of using the structured telemetry/logging pipeline, which violates the style guidelines for production code.</violation>
</file>
<file name="packages/workflow/src/run-execution-data/run-execution-data.ts">
<violation number="1" location="packages/workflow/src/run-execution-data/run-execution-data.ts:35">
Rule violated: **Prefer Typeguards over Type casting**
`migrateRunExecutionData` now ends with a bare `as` cast, so the union `IRunExecutionDataAll` is forced into `IRunExecutionData` without a type guard or discriminant-based narrowing, violating the “Prefer Typeguards over Type casting” rule and hiding missing migrations.</violation>
</file>
<file name="packages/@n8n/db/src/repositories/execution.repository.ts">
<violation number="1" location="packages/@n8n/db/src/repositories/execution.repository.ts:221">
Rule violated: **Prefer Typeguards over Type casting**
The updated execution loaders still narrow the parsed payload with `parse(executionData.data) as IRunExecutionDataAll`, which violates the “Prefer type guards over type casting” rule. Introduce a typed variable or guard that proves the value matches `IRunExecutionDataAll` before calling `migrateRunExecutionData`, rather than asserting with `as`.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| // Fall through to subsequent versions as they're added. | ||
| } | ||
| // NOTE: it's safe to assert here because we have handled all previous versions. | ||
| return data as IRunExecutionData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rule violated: Prefer Typeguards over Type casting
migrateRunExecutionData now ends with a bare as cast, so the union IRunExecutionDataAll is forced into IRunExecutionData without a type guard or discriminant-based narrowing, violating the “Prefer Typeguards over Type casting” rule and hiding missing migrations.
Prompt for AI agents
Address the following comment on packages/workflow/src/run-execution-data/run-execution-data.ts at line 35:
<comment>`migrateRunExecutionData` now ends with a bare `as` cast, so the union `IRunExecutionDataAll` is forced into `IRunExecutionData` without a type guard or discriminant-based narrowing, violating the “Prefer Typeguards over Type casting” rule and hiding missing migrations.</comment>
<file context>
@@ -20,6 +20,17 @@ const __brand = Symbol('brand');
+ // Fall through to subsequent versions as they're added.
+ }
+ // NOTE: it's safe to assert here because we have handled all previous versions.
+ return data as IRunExecutionData;
+}
</file context>
✅ Addressed in db58367
| return { | ||
| ...rest, | ||
| data: parse(executionData.data) as IRunExecutionData, | ||
| data: migrateRunExecutionData(parse(executionData.data) as IRunExecutionDataAll), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rule violated: Prefer Typeguards over Type casting
The updated execution loaders still narrow the parsed payload with parse(executionData.data) as IRunExecutionDataAll, which violates the “Prefer type guards over type casting” rule. Introduce a typed variable or guard that proves the value matches IRunExecutionDataAll before calling migrateRunExecutionData, rather than asserting with as.
Prompt for AI agents
Address the following comment on packages/@n8n/db/src/repositories/execution.repository.ts at line 221:
<comment>The updated execution loaders still narrow the parsed payload with `parse(executionData.data) as IRunExecutionDataAll`, which violates the “Prefer type guards over type casting” rule. Introduce a typed variable or guard that proves the value matches `IRunExecutionDataAll` before calling `migrateRunExecutionData`, rather than asserting with `as`.</comment>
<file context>
@@ -217,7 +218,7 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
return {
...rest,
- data: parse(executionData.data) as IRunExecutionData,
+ data: migrateRunExecutionData(parse(executionData.data) as IRunExecutionDataAll),
workflowData: executionData.workflowData,
customData: Object.fromEntries(metadata.map((m) => [m.key, m.value])),
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR doesn't change the behaviour here - we were always asserting. We trust that only IRunExecutionData (of some version) has been written to the database.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Clarify the difference between inclusive and exclusive execution modes for destination nodes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Remove unnecessary isRunExecutionDataV1 type guard - Use direct version check instead - Simplify type assertions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Add default value for options parameter - Remove unnecessary type annotations (inferred by TypeScript) - Use non-optional chaining with default parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…rvice TypeScript can infer the type from the ternary expression. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Mark that destinationNode field needs to be updated from string to IDestinationNode to complete CAT-1265 properly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Refactor 3 test cases to use the proper factory function instead of manually constructing error execution data. This makes tests more maintainable and ensures consistent structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add tests for both execution order versions (v0 and v1) to verify: - Exclusive mode: destination node does not execute - Inclusive mode: destination node executes Also add tests for checkReadyForExecution to verify: - Exclusive mode: destination node is not checked for issues - Inclusive mode: destination node is checked for issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
despairblue
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some small changes (adding tests, removing some types that can be inferred, adding a todo, etc.). Please check them out and let me know if you agree with them.
Rest look really good. Nice job!
Summary
Internally switch to use a structured DestinationNode by making RunExecutionDataV1 the default.
Externally, nothing changes - the controller still accepts the old format and passes
mode: 'inclusive'to preserve the existing behaviour. The next PR will make the change in the API and frontend to actually fix the original bug.This PR also adds code to migrate records to the latest version of RunExecutionData, and uses this to make sure we can still read old records in the database. It adds an e2e test to verify that this happens in the execution repository.
Finally, this PR also updates the various (many) places that handle the destination node to process the new structure.
Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/CAT-1265
Review / Merge checklist
release/backport(if the PR is an urgent fix that needs to be backported)