anomalyco/sst · error · VisibleError

Cannot access `nodes.loadBalancer` in dev mode.

Error message

Cannot access `nodes.loadBalancer` in dev mode.

What it means

The `nodes.loadBalancer` getter on the v1 `Service` component returns the ALB resource created when public ports are exposed. In `sst dev` mode no load balancer is provisioned, so accessing the getter throws this `VisibleError` before the more specific 'no public ports' check can run.

Source

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

      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;
      },
    };
  }

  /** @internal */
  public getSSTLink() {
    return {
      properties: { url: $dev ? this.devUrl : this._url },
    };
  }
}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Wrap the access in `if (!$dev)`.
  2. Use `service.url` in dev mode to get the dev endpoint instead of the ALB DNS name.
  3. Configure routing via the `loadBalancer` prop (rules/ports) rather than mutating `nodes.loadBalancer` post-hoc.

Example fix

// before
const dns = svc.nodes.loadBalancer.loadBalancer.dnsName;

// after
if (!$dev) {
  const dns = svc.nodes.loadBalancer.loadBalancer.dnsName;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!$dev) {
  const lb = myService.nodes.loadBalancer;
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Accessing `service.nodes.loadBalancer` during `sst dev`, regardless of whether public ports are configured.

Common situations: Adding listeners/rules to the ALB or referencing the ALB DNS name in other components from code that also runs in dev mode.

Related errors


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