mastra-ai/mastra · error · Error

Duplicate worker name "${w.name}" in the 'workers' option

Error message

Duplicate worker name "${w.name}" in the 'workers' option

What it means

When constructing the Mastra instance, custom workers from the 'workers' option are scanned for duplicate names; the constructor throws a plain Error naming the duplicated worker so worker resolution stays unambiguous. Default workers sharing a custom worker's name are silently replaced by the custom one, but duplicates inside the custom array fail loudly.

Source

Thrown at packages/core/src/mastra/index.ts:1418

      // `handleWorkflowEvent` directly to the pubsub during startWorkers().
      const pubsubModes = this.#pubsub.supportedModes ?? ['pull'];
      const defaultWorkers: MastraWorker[] = [];
      if (pubsubModes.includes('pull')) {
        defaultWorkers.push(new OrchestrationWorker());
      }
      // SchedulerWorker is added in startWorkers() rather than here so its
      // storage-backed runtime is only initialized when workers actually start.
      if (config?.backgroundTasks?.enabled) {
        defaultWorkers.push(new BackgroundTaskWorker(config.backgroundTasks));
      }
      // Merge custom workers with the defaults: a custom worker replaces a
      // default sharing its name (e.g. a custom OrchestrationWorker), and
      // duplicate names within the custom array fail loud.
      const customWorkers = workersOption ?? [];
      const customNames = new Set<string>();
      for (const w of customWorkers) {
        if (customNames.has(w.name)) {
          throw new Error(`Duplicate worker name "${w.name}" in the 'workers' option`);
        }
        customNames.add(w.name);
      }
      this.#workers = [...defaultWorkers.filter(w => !customNames.has(w.name)), ...customWorkers];
      for (const w of this.#workers) {
        w.__registerMastra(this);
      }
    }

    let logger: TLogger;
    if (config?.logger === false) {
      logger = noopLogger as unknown as TLogger;
      this.#loggerExplicit = true;
    } else {
      if (config?.logger) {
        logger = config.logger;
        this.#loggerExplicit = true;
      } else {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Give each custom worker in the workers array a unique name.
  2. Deduplicate the array before constructing Mastra (e.g. new Map(workers.map(w => [w.name, w])).values()).
  3. If the same worker instance is included twice, include it once.
  4. Fix loop code that assigns a constant name instead of a per-item name.

Example fix

// before
new Mastra({ workers: [new MyWorker({ name: 'ingest' }), new MyWorker({ name: 'ingest' })] });
// after
new Mastra({ workers: [new MyWorker({ name: 'ingest' }), new MyWorker({ name: 'enrich' })] });
Defensive patterns

Strategy: validation

Validate before calling

const names = (workersOption ?? []).map(w => w.name);
const dupes = names.filter((n, i) => names.indexOf(n) !== i);
if (dupes.length) throw new Error(`Duplicate worker names: ${dupes.join(', ')}`);
new Mastra({ workers: workersOption });

Type guard

function hasUniqueWorkerNames(ws: { name: string }[]): ws is { name: string }[] {
  return new Set(ws.map(w => w.name)).size === ws.length;
}

Try / catch

try {
  const mastra = new Mastra({ workers });
} catch (e) {
  if (e instanceof Error && e.message.includes('Duplicate worker name')) {
    workers = [...new Map(workers.map(w => [w.name, w])).values()];
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing Mastra({ workers: [...] }) where two custom workers in the array have the same .name property (including two instances of the same custom OrchestrationWorker).

Common situations: Spreading a workers array that accidentally contains the same worker twice; generating workers in a loop with a fixed name; copy-pasting a worker config without renaming it.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/052ac4a5a9113902. Report an issue: GitHub.