anomalyco/sst · error · VisibleError

Cannot access `nodes.taskDefinition` in dev mode.

Error message

Cannot access `nodes.taskDefinition` in dev mode.

What it means

The `nodes.taskDefinition` getter on the v1 `Service` component returns the ECS Task Definition resource. In `sst dev` mode the task definition is not deployed (the app runs through the dev proxy), so SST raises a `VisibleError` explaining that the property cannot be accessed in dev mode.

Source

Thrown at platform/src/components/aws/service-v1.ts:824

       * The Amazon ECS Service.
       */
      get service() {
        if ($dev)
          throw new VisibleError("Cannot access `nodes.service` in dev mode.");
        return self.service!;
      },
      /**
       * The Amazon ECS Task Role.
       */
      get taskRole() {
        return self.taskRole;
      },
      /**
       * The Amazon ECS Task Definition.
       */
      get taskDefinition() {
        if ($dev)
          throw new VisibleError(
            "Cannot access `nodes.taskDefinition` in dev mode.",
          );
        return self.taskDefinition!;
      },
      /**
       * The Amazon Elastic Load Balancer.
       */
      get loadBalancer() {
        if ($dev)
          throw new VisibleError(
            "Cannot access `nodes.loadBalancer` in dev mode.",
          );
        if (!self.loadBalancer)
          throw new VisibleError(
            "Cannot access `nodes.loadBalancer` when no public ports are exposed.",
          );
        return self.loadBalancer;
      },

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Guard the access with `if (!$dev)` so it only executes on deploy.
  2. Access the task role via `nodes.taskRole` only in non-dev branches, or use component-level APIs that work in dev.
  3. Move resource-wiring code into the component constructor arguments (e.g. `permissions` prop) which supports dev mode.

Example fix

// before
bucket.grantRead(myService.nodes.taskDefinition.taskRole);

// after
if (!$dev) {
  bucket.grantRead(myService.nodes.taskDefinition.taskRole);
} else {
  // use myService.nodes.taskRole or the permissions prop
}
Defensive patterns

Strategy: validation

Validate before calling

if (!$dev) {
  const td = myService.nodes.taskDefinition;
}

Type guard

const isDeploy = (): boolean => !($dev as boolean);

Try / catch

try {
  return myService.nodes.taskDefinition;
} catch (e) {
  if (e instanceof VisibleError && e.message.includes("taskDefinition")) return undefined;
  throw e;
}

Prevention

When it happens

Trigger: Reading `service.nodes.taskDefinition` while `sst dev` is active, e.g. to reference the task definition ARN, add task role policies, or inspect container definitions.

Common situations: Granting extra IAM permissions to the task role or attaching the service to other AWS resources in shared code that executes during the dev loop.

Related errors


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