anomalyco/sst · error · RunError

Failed to run task

Error message

Failed to run task

What it means

`task.run` calls the ECS RunTask API via awsFetch. If the HTTP response is not OK, a `RunError` with message "Failed to run task" is thrown, with the raw `Response` attached as `error.response` for reading the AWS error detail (e.g. AccessDeniedException, No cluster found).

Source

Thrown at sdk/js/src/aws/task.ts:266

        },
        overrides: {
          ...(options?.cpu ? { cpu: (parseFloat(options.cpu.replace(" vCPU", "")) * 1024).toString() } : {}),
          ...(options?.memory ? { memory: (parseFloat(options.memory.replace(" GB", "")) * 1024).toString() } : {}),
          ...(options?.storage ? { ephemeralStorage: { sizeInGiB: parseInt(options.storage.replace(" GB", "")) } } : {}),

          containerOverrides: resource.containers.map((name) => ({
            name,
            environment: Object.entries(environment ?? {}).map(
              ([key, value]) => ({
                name: key,
                value,
              })
            ),
          })),
        },
      }),
    }, options);
    if (!res.ok) throw new RunError(res);

    const data = (await res.json()) as {
      tasks?: {
        taskArn: string;
        lastStatus: string;
      }[];
    };
    if (!data.tasks?.length) throw new RunError(res);

    return {
      arn: data.tasks[0].taskArn,
      status: data.tasks[0].lastStatus,
      response: data,
    };
  }

  /**
   * Stops a task.

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Read `error.response` body for the exact AWS error code.
  2. Grant the caller's IAM role `ecs:RunTask` plus `iam:PassRole` on the task execution/role.
  3. Verify the linked task resource's cluster and task definition exist in the current stage (redeploy if needed).
  4. Check ECS capacity/launch type settings; retry with backoff on capacity-related throttling errors.

Example fix

try {
  const ret = await task.run(Resource.MyTask, { message: body });
} catch (e) {
  if (e instanceof task.RunError) {
    console.error(await e.response.text());
  }
}
Defensive patterns

Strategy: retry

Validate before calling

import { Resource } from "sst";
if (!Resource.MyTask?.cluster) throw new Error("Task resource not linked to this function; add `link: [Resource.MyTask]`");

Type guard

function isRunError(e: unknown): e is task.RunError {
  return e instanceof task.RunError && typeof e.response === "object";
}

Try / catch

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    return await task.run(Resource.MyTask, input);
  } catch (e) {
    if (!isRunError(e) || e.response.status < 500) throw e;
    await new Promise(r => setTimeout(r, 2 ** attempt * 200));
  }
}
throw new Error("RunTask failed after retries");

Prevention

When it happens

Trigger: Calling `task.run(resource, ...)` where the ECS RunTask request returns non-OK: missing IAM `ecs:RunTask` permission, cluster doesn't exist, invalid task definition family, missing `iam:PassRole` for the task role, or no capacity available.

Common situations: Function's IAM role lacks ecs:RunTask and iam:PassRole; task definition family renamed across deploys; Fargate cluster has no capacity in the AZ; environment variables referencing removed resources; launching before the first deploy finished creating the cluster.

Related errors


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