Skip to content

bug: scoped request-idempotency hashes are rejected by UUID validation in v4.5.16 #4914

Description

@ThomasKirst

Provide environment information

Self-hosted Trigger.dev, official v4.5.16 webapp image.

Host OS: Ubuntu 24.04.1 LTS
Architecture: x86_64
Node.js inside the webapp container: v24.18.0

Image digest:
sha256:db0d3be25c2d49ccb3089666b201bc07d932fb5e50b6a080e755973c58378cc3

Image source revision:
cc0049c

Reproduced on our self-hosted Trigger.dev v4.5.16 instance on 9 September 2026 using a harmless test task and direct HTTP requests, without automatic HTTP retries.

Describe the bug

Sending two sequential, identical task-trigger requests with the same valid UUID in x-trigger-request-idempotency-key creates two distinct runs. Both runs execute.

The server logs:
RequestIdempotency: invalid requestIdempotencyKey

The rejected value is a 64-character hash generated internally by Trigger.

Expected: once the first request succeeds, repeating it with the same request key should return the existing run.

Actual: both responses return different run IDs and isCached: false.

As a control, repeating the test with an additional task-level idempotency-key correctly returns the same run ID, with isCached: true on the second response.

Reproduction repo

No standalone public reproduction repository. Self-contained task and HTTP reproduction instructions are provided below.

To reproduce

We verified this using an existing harmless smoke task. This minimal equivalent task can be used to reproduce the request behaviour:

import { task } from "@trigger.dev/sdk";

export const requestIdempotencyRepro = task({
  id: "request-idempotency-repro",
  run: async (payload: { nonce: string }) => payload,
});
  1. Deploy the task to a test environment on self-hosted v4.5.16.
  2. Set TRIGGER_API_URL and TRIGGER_SECRET_KEY for that environment.
  3. Send two sequential requests with the same request key and payload:
REQUEST_KEY="$(uuidgen)"

for attempt in 1 2; do
  curl --silent --show-error --fail-with-body \
    --request POST \
    "${TRIGGER_API_URL%/}/api/v1/tasks/request-idempotency-repro/trigger" \
    --header "Authorization: Bearer ${TRIGGER_SECRET_KEY}" \
    --header "Content-Type: application/json" \
    --header "x-trigger-request-idempotency-key: ${REQUEST_KEY}" \
    --data '{"payload":{"nonce":"request-idempotency-repro"}}'
  echo
done
  1. Compare the returned run IDs and inspect the server's invalid-key warnings.
  2. For a control, generate a fresh request key and repeat with an additional idempotency-key header. Keep both keys identical across the two control requests.

Our verified results:

Test First response Second response
Request key only Run A, isCached: false Run B, isCached: false
Request key plus task-level key Run C, isCached: false Run C, isCached: true

Runs A and B both completed with the same payload and output. Run C also completed.

Additional information

The source revision corresponding to our deployed image shows an apparent format mismatch:

  1. The task-trigger route scopes the request key by environment ID and task ID.
  2. scopeRequestIdempotencyKey() produces a SHA-256 hexadecimal digest.
  3. RequestIdempotencyService only accepts UUIDv4 keys, so it rejects the generated digest and skips both cache lookup and storage.

Source:

Matching invalid-key warnings appeared during both tests.

We confirmed duplicate execution by deliberately resending a request. This could affect retries after an accepted request's response is lost, although we did not simulate a network failure or attribute any real business-side duplicates to this defect.

Any fix should preserve environment/task isolation.

Could you confirm whether this is already tracked?

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions