Solution skill
Inngest: dont mutate closure variables inside step.run()
Complete solution
When you aggregate results across Inngest steps, return values from step.run() and combine them in the outer scope instead of mutating closure variables inside callbacks. Use this skill when the task matches the title above. Not for unrelated tools or errors; check the tool's own docs for those.
TL;DR
When you aggregate results across Inngest steps, return values from step.run() and combine them in the outer scope instead of mutating closure variables inside callbacks. Memoized steps skip their callback bodies on replay, so any counter incremented there misses on resume. Inngest replays the function body but memoizes completed steps, so increments inside already-completed callbacks dont re-run on replay.
Fix
When you aggregate results across Inngest steps, return values from step.run() and combine them in the outer scope instead of mutating closure variables inside callbacks. Memoized steps skip their callback bodies on replay, so any counter incremented there misses on resume.
Context: Inngest audit notes (smj1860/fieldstay): counters declared in the outer function scope and mutated inside step.run() callbacks are fragile. Inngest replays the function body but memoizes completed steps, so increments inside already-completed callbacks dont re-run on replay. Counts can silently undercount after partial failures or refactors.
Matched source
Source: Published skill Original query: "Inngest: dont mutate closure variables inside step.run()" Key terms: closure, dont, inngest, inside, mutate, step, variables
When to use this
- Use this when your task, error, or question matches the title above and the setup in the Fix section.
When not to use this
- Skip it when the error text, tool, or situation is different. Forcing a mismatched fix usually costs more time than searching again.
Compatibility
The original write-up does not pin tool versions. Treat the commands and UI paths above as reflecting the author's setup, and check your tool's own docs if your version looks different.
Evidence
Source: Inngest audit notes (smj1860/fieldstay): counters declared in the outer function scope and mutated inside step.run() callbacks are fragile. Inngest replays the function body but memoizes completed steps, so increments inside already-completed callbacks dont re-run on replay. Counts can silently undercount after partial failures or refactors.
Verified resolution: When you aggregate results across Inngest steps, return values from step.run() and combine them in the outer scope instead of mutating closure variables inside callbacks. Memoized steps skip their callback bodies on replay, so any counter incremented there misses on resume.
Source URL: https://github.com/smj1860/fieldstay/blob/HEAD/audit/round1/02-idempotency-inngest.md
By @issueatlas · Version 3 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_d1K43pclgFV_Npn59lHXYQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Inngest: dont mutate closure variables inside step.run() <span>— Vectle</span></a>