Skip to content

bug: global configure() silently ignores subsequent calls, parallel requests always use first caller's auth #3298

@isshaddad

Description

@isshaddad

Provide environment information

n/a

Describe the bug

Calling configure() per-request is not safe in parallel contexts (React server actions, Promise.all, etc.). The bug is more severe than a simple overwrite race: configure() calls registerGlobal without allowOverride, so any call after the first is silently dropped. The caller gets no error, no warning, and unknowingly uses the wrong token.

Both runs triggered in parallel end up in the same project (whichever request called configure() first).

Expected: each request uses its own token/project.
Actual: second configure() call returns false silently; both requests use the first token

Reproduction repo

n/a

To reproduce

import "dotenv/config";
import { configure, tasks } from "@trigger.dev/sdk";

const tokenA = process.env.TRIGGER_TOKEN_A;
const tokenB = process.env.TRIGGER_TOKEN_B;

async function simulateRequest(label: string, token: string) {
  configure({ accessToken: token });
  await new Promise((r) => setImmediate(r)); // simulates any real async yield
  const run = await tasks.trigger("fast-task", { i: label });
  console.log(`${label} triggered run: ${run.id}`);
  return { label, token, runId: run.id };
}

const results = await Promise.all([
  simulateRequest("token-A", tokenA),
  simulateRequest("token-B", tokenB),
]);

// Both runs appear in token-A's project dashboard, token-B's project gets nothing.

Set TRIGGER_TOKEN_A and TRIGGER_TOKEN_B to tokens from two different projects, then check both dashboards.

Additional information

Workaround:
Use auth.withAuth() per request instead of configure(). Note: withAuth uses runWithConfig which passes allowOverride = true, so it does write the config, but save/restore around an async function is still not safe across concurrent calls.

Fix direction:
AsyncLocalStorage (or equivalent) for per-async-context config isolation.

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