anomalyco/sst · error · VisibleError

You cannot provide both "job" and "worker" in the "${name}"

Error message

You cannot provide both "job" and "worker" in the "${name}" Cron component. The "job" property has been deprecated. Use "worker" instead.

What it means

The Cloudflare Cron component's `job` property is deprecated in favor of `worker`. Providing both makes the intent ambiguous, so SST throws immediately during argument normalization instead of guessing.

Source

Thrown at platform/src/components/cloudflare/cron.ts:156

 */
export class Cron extends Component {
  private worker: WorkerBuilder;
  private trigger: Output<cf.WorkerCronTrigger>;

  constructor(name: string, args: CronArgs, opts?: ComponentResourceOptions) {
    super(__pulumiType, name, args, opts);

    const parent = this;

    const workerArgs = normalizeWorker();
    const worker = createWorker();
    const trigger = createTrigger();
    this.worker = worker;
    this.trigger = trigger;

    function normalizeWorker() {
      if (args.job && args.worker)
        throw new VisibleError(
          `You cannot provide both "job" and "worker" in the "${name}" Cron component. The "job" property has been deprecated. Use "worker" instead.`,
        );
      return args.worker ?? args.job;
    }

    function createWorker() {
      if (!workerArgs)
        throw new VisibleError(
          `You must provide a "worker" for the "${name}" Cron component.`,
        );
      return workerBuilder(`${name}Handler`, workerArgs, undefined, undefined, args.accountId);
    }

    function createTrigger() {
      return all([args.schedules]).apply(([schedules]) => {
        return new cloudflare.WorkersCronTrigger(
          ...transform(
            args.transform?.trigger,

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Remove the deprecated `job` property and keep only `worker`.
  2. If you intended the old behavior only, remove `worker` and keep `job` (deprecated, so migrate eventually).

Example fix

// before
new sst.cloudflare.Cron(app, "Cron", {
  job: { scriptPath: "./src/job.ts" },
  worker: { scriptPath: "./src/worker.ts" },
});
// after
new sst.cloudflare.Cron(app, "Cron", {
  worker: { scriptPath: "./src/worker.ts" },
});
Defensive patterns

Strategy: validation

Validate before calling

const cronArgs = { job: undefined, worker: { handler: "./src/worker.ts" } };
if (cronArgs.job && cronArgs.worker) throw new Error("Provide only 'worker' ('job' is deprecated)");

Type guard

const usesOnlyWorker = (a: { job?: unknown; worker?: unknown }) =>
  a.worker != null && a.job == null;

Try / catch

try {
  new sst.cloudflare.Cron(app, "Cron", cronArgs);
} catch (e) {
  if (String(e).includes('both "job" and "worker"')) console.error("Remove deprecated 'job' property");
  else throw e;
}

Prevention

When it happens

Trigger: Defining a `sst.cloudflare.Cron` with both `job: {...}` and `worker: {...}` set in the same component args; normalizeWorker() detects both and throws at synth time.

Common situations: Migrating an existing Cron from `job` to `worker` and adding the new key before removing the old one; copy-pasting example configs that mix old and new API.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/9199e50c23e26c87. Report an issue: GitHub.