Skip to content

docs: idempotency keys deduplicate triggers, not side effects inside run() - #4952

Merged
matt-aitken merged 1 commit into
mainfrom
docs/idempotency-key-scope-triggers
Sep 18, 2026
Merged

matt-aitken merged 1 commit into
mainfrom
docs/idempotency-key-scope-triggers

Conversation

@matt-aitken

Copy link
Copy Markdown
Member

Summary

Idempotency keys deduplicate task triggers (trigger(), triggerAndWait(), batchTrigger()). They do not make the code inside a task's run() idempotent: when a run retries, run() executes again from the top, and any API call inside it happens again unless that call is itself idempotent.

The idempotency page listed "avoiding double-charging customers" as a use case, but every example on the page only ever deduplicated a child trigger, so a reader could reasonably assume a payment call made directly inside a retryable run() was protected. It is not, and no Trigger.dev-side mechanism can protect it: only the payment provider can deduplicate its own API call, so the provider's idempotency key has to be passed too.

This is a docs-only change. No SDK changes.

What changed

  • The intro now states the boundary up front: the key applies to the trigger call and nothing else.
  • The use-case bullets say "trigger the X task once" rather than implying the side effect itself is deduplicated, and the payments bullet points at the new section.
  • A new "Side effects inside run()" section explains why moving the call into a child task does not close the gap either, and shows a Stripe refund passing Stripe's idempotencyKey alongside a Trigger.dev key for the follow-up email trigger.

Addresses the documentation side of #4627. Supersedes #4650, which was auto-closed by the vouch gate.

…run()

The idempotency page listed avoiding double charges as a use case, but its
examples only ever deduplicate a child trigger. A payment call made directly
inside a retryable run() gets no protection from the Trigger.dev key. The
page now states the boundary up front and adds a section showing the
provider's own idempotency key (Stripe) alongside the Trigger.dev key.
@changeset-bot

changeset-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5b4b28f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

Comment thread docs/idempotency.mdx
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: df94b3bc-c737-434f-b9f6-1a0b6f7c1260

📥 Commits

Reviewing files that changed from the base of the PR and between 34c2d69 and 5b4b28f.

📒 Files selected for processing (1)
  • docs/idempotency.mdx

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
MDX documentation pages must include frontmatter with title (required), description (required), and sidebarTitle (optional) in YAML format Use Mintlify components for structured content: , , , , ,

📄 CodeRabbit inference engine (docs/CLAUDE.md)

Files:

  • docs/idempotency.mdx
🧠 Learnings (1)
📚 Learning: 2026-04-30T20:30:29.458Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3226
File: docs/ai-chat/quick-start.mdx:13-13
Timestamp: 2026-04-30T20:30:29.458Z
Learning: In this repo’s documentation MDX files (`docs/**/*.mdx`), use `ts` and `tsx` (not `typescript`) as the code-fence language tags for TypeScript/TSX snippets. Do not flag `ts`/`tsx` code-fence language tags as incorrect in any docs MDX file, since this is the site-wide Mintlify-compatible convention.

Applied to files:

  • docs/idempotency.mdx
🪛 LanguageTool
docs/idempotency.mdx

[style] ~43-~43: This sentence contains multiple usages of the word “again”. Consider removing or replacing it.
Context: ...abase write, or email inside it happens again unless that operation is itself idempot...

(REPETITION_OF_AGAIN)

🔇 Additional comments (1)
docs/idempotency.mdx (1)

6-8: LGTM!

Also applies to: 36-73


Walkthrough

The idempotency documentation now states that keys deduplicate trigger(), triggerAndWait(), and batchTrigger(). It clarifies that keys do not make code inside run() idempotent. The use cases now focus on duplicate triggers. A new section explains that retries rerun run() and shows how to use a provider-specific idempotency key for Stripe refunds or record side effects in a database.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 5b4b2

The guide clarifies retry side-effect behavior without changing runtime code. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the motivation, scope, and changes clearly, but it omits required template sections for the checklist, testing steps, changelog, and screenshots. It also references issues wit… Add the required checklist, testing details, changelog, and screenshots sections. Include the relevant issue using the template's Closes # format, or explain why that format does not apply.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main documentation change: trigger idempotency keys do not make side effects inside run() idempotent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the motivation, scope, and changes clearly, but it omits required template sections for the checklist, testing steps, changelog, and screenshots. It also references issues without using the required Closes #<issue> format.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@matt-aitken
matt-aitken added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit adc4979 Sep 18, 2026
32 checks passed
@matt-aitken
matt-aitken deleted the docs/idempotency-key-scope-triggers branch September 18, 2026 10:13
pull Bot pushed a commit to erickirt/trigger.dev that referenced this pull request Sep 18, 2026
…iggerdotdev#4953)

## Summary

Follow-up to
[triggerdotdev#4952](triggerdotdev#4952). The new
"Side effects inside `run()`" section told readers to derive the
provider's idempotency key from a payload ID, but the more general
answer is the run ID: `ctx.run.id` is stable across every attempt of a
run, is always available, and is the same value the default `run` scope
already mixes into a Trigger.dev idempotency key.

The Stripe refund example now keys the provider call on `ctx.run.id`,
and a short paragraph explains when a business ID from the payload is
the better choice (when the same task can be triggered more than once
for the same order and you want deduplication across separate runs).

Docs only.
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.

2 participants