Skip to content

Commit d113251

Browse files
authored
Add 'Pass-by-Value Semantics' section to serialization docs (#254)
Signed-off-by: Nathan Rajlich <n@n8.io>
1 parent c43bc2a commit d113251

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

.changeset/tough-wasps-notice.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

docs/content/docs/foundations/serialization.mdx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,45 @@ export async function handleWebhookWorkflow() {
152152
//
153153
}
154154
```
155+
156+
## Pass-by-Value Semantics
157+
158+
**Parameters are passed by value, not by reference.** Steps receive deserialized copies of data. Mutations inside a step won't affect the original in the workflow.
159+
160+
**Incorrect:**
161+
162+
```typescript
163+
export async function updateUserWorkflow(userId: string) {
164+
"use workflow";
165+
166+
let user = { id: userId, name: "John", email: "john@example.com" };
167+
await updateUserStep(user);
168+
169+
// user.email is still "john@example.com"
170+
console.log(user.email);
171+
}
172+
173+
async function updateUserStep(user: { id: string; name: string; email: string }) {
174+
"use step";
175+
user.email = "newemail@example.com"; // Changes are lost
176+
}
177+
```
178+
179+
**Correct - return the modified data:**
180+
181+
```typescript
182+
export async function updateUserWorkflow(userId: string) {
183+
"use workflow";
184+
185+
let user = { id: userId, name: "John", email: "john@example.com" };
186+
user = await updateUserStep(user); // Reassign the return value
187+
188+
console.log(user.email); // "newemail@example.com"
189+
}
190+
191+
async function updateUserStep(user: { id: string; name: string; email: string }) {
192+
"use step";
193+
user.email = "newemail@example.com";
194+
return user;
195+
}
196+
```

docs/content/docs/foundations/workflows-and-steps.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ async function chargePayment(order: Order) {
7979

8080
By default, steps have a maximum of 3 retry attempts before they fail and propagate the error over to the workflow. Learn more about errors and retrying in the [Errors & Retrying](/docs/foundations/errors-and-retries) page.
8181

82+
<Callout type="warning">
83+
**Important:** Due to serialization, parameters are passed by **value, not by reference**. If you pass an object or array to a step and mutate it, those changes will **not** be visible in the workflow context. Always return modified data from your step functions instead. See [Pass-by-Value Semantics](/docs/foundations/serialization#pass-by-value-semantics) for details and examples.
84+
</Callout>
85+
8286
<Callout type="info">
8387
Step functions are primarily meant to be used inside a workflow.
8488
</Callout>

0 commit comments

Comments
 (0)