Skip to content

Add experimental support for deferred functions#1508

Draft
amh4r wants to merge 5 commits intomainfrom
deferred-functions
Draft

Add experimental support for deferred functions#1508
amh4r wants to merge 5 commits intomainfrom
deferred-functions

Conversation

@amh4r
Copy link
Copy Markdown
Contributor

@amh4r amh4r commented May 1, 2026

⚠️ Depends on inngest/inngest#4010. CI will not pass until we release these changes in the Dev Server.

Summary

Add experimental support for deferred functions. These are a new type of Inngest function that behave like a fire-and-forget step.invoke. They allow you to defer work in the background without blocking your Inngest function. This will eventually support AI scoring.

Read defer.md for more detail.

Checklist

  • Added unit/integration tests
  • Added changesets if applicable

Note

Adds experimental deferred functions (createDefer / defer()): a fire-and-forget mechanism for triggering independent Inngest functions with typed payloads. Introduces DeferredFunction (a subclass of InngestFunction with an implicit inngest/deferred.schedule trigger), a DeferAdd lazy opcode that buffers in LazyOps and drains onto the next outbound wire message, priorDefers for replay deduplication, and handlerKind replacing the boolean isFailureHandler.

Written by Mendral for commit 55cbe07.

@amh4r amh4r requested a review from Linell May 1, 2026 21:16
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 1, 2026

🦋 Changeset detected

Latest commit: 11e4211

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
inngest Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@inngest-release-bot inngest-release-bot added the 📦 inngest Affects the `inngest` package label May 1, 2026
@amh4r amh4r marked this pull request as draft May 1, 2026 21:17
Copy link
Copy Markdown

@mendral-app mendral-app Bot left a comment

Choose a reason for hiding this comment

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

High risk — 1 issue in 1 file

The defer function is spread directly into fnArg at engine.ts:2051, which is the same object passed to every step middleware hook (transformStepInput, onStepStart, etc.). This causes all integration tests to fail because middleware ctx now has 9 properties instead of 8. The fix is to keep defer out of fnArg and inject it only at the handler call site.

Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.

<assessment>
The `defer` function is spread directly into `fnArg` at engine.ts:2051, which is the same object passed to every step middleware hook (`transformStepInput`, `onStepStart`, etc.). This causes all integration tests to fail because middleware ctx now has 9 properties instead of 8. The fix is to keep `defer` out of `fnArg` and inject it only at the handler call site.
</assessment>

<file name="packages/inngest/src/components/execution/engine.ts">
<issue location="packages/inngest/src/components/execution/engine.ts:2042">
`defer` is spread into `fnArg`, which is passed verbatim to every step middleware hook (`transformStepInput`, `onStepStart`, etc.). This causes all integration tests to fail — middleware ctx has 9 properties instead of 8. `defer` should only be available in the handler call, not in middleware ctx.
</issue>
</file>

Tag @mendral-app with feedback or questions. View session

Comment on lines 2042 to +2052
@@ -1868,12 +2048,22 @@ class InngestExecutionEngine
...(this.options.data as { event: EventPayload }),
step,
group: createGroupTools({ experimentStepRun }),
} as Context.Any;
defer,
} as unknown as Context.Any;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

bug (P0): defer is spread into fnArg, which is passed verbatim to every step middleware hook (transformStepInput, onStepStart, etc.). This causes all integration tests to fail — middleware ctx has 9 properties instead of 8. defer should only be available in the handler call, not in middleware ctx.

Suggested change
Suggested change
const { step, defer } = this.createStepTools();
const experimentStepRun = (step as unknown as ExperimentStepTools)[
experimentStepRunSymbol
];
let fnArg = {
...(this.options.data as { event: EventPayload }),
step,
group: createGroupTools({ experimentStepRun }),
} as unknown as Context.Any;
// Attach defer separately so it is available to the handler but not
// leaked into step-middleware ctx (transformStepInput, onStepStart, etc.).
(fnArg as unknown as { defer: typeof defer }).defer = defer;
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/inngest/src/components/execution/engine.ts, line 2042:

<issue>
`defer` is spread into `fnArg`, which is passed verbatim to every step middleware hook (`transformStepInput`, `onStepStart`, etc.). This causes all integration tests to fail — middleware ctx has 9 properties instead of 8. `defer` should only be available in the handler call, not in middleware ctx.
</issue>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📦 inngest Affects the `inngest` package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants