anomalyco/sst · error · VisibleError
Cannot access `nodes.loadBalancer` when no public ports are
Error message
Cannot access `nodes.loadBalancer` when no public ports are exposed.
What it means
This is the deploy-time counterpart to the dev-mode guard: `nodes.loadBalancer` is only valid when the Service was created with public ports exposed. If no load balancer exists (`self.loadBalancer` is undefined), SST throws this `VisibleError` to explain that the property is unavailable rather than returning undefined.
Source
Thrown at platform/src/components/aws/service-v1.ts:838
* 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 },
};
}
}
const __pulumiType = "sst:aws:Service";
// @ts-expect-error
Service.__pulumiType = __pulumiType;View on GitHub (pinned to a0bd20f762)
Solutions
- Expose at least one public port via the `public` ports config so a load balancer is created.
- Guard the access: check `if (!$dev)` and only read `nodes.loadBalancer` for services with public ports.
- If the service must be internal, reference your own separately-created `sst.aws.LoadBalancer` component instead.
Example fix
// before
const lb = svc.nodes.loadBalancer;
// after
const svc = new sst.aws.Service("Api", {
containers: [{ name: "app", image: "...", public: { ports: [{ http: 80 }] } }]
});
const lb = svc.nodes.loadBalancer; // now valid Defensive patterns
Strategy: validation
Validate before calling
// ensure the Service config exposes public ports before reading nodes.loadBalancer
const hasPublicPorts = (args: sst.aws.ServiceArgs) =>
args.containers?.some((c) => c.public?.ports && c.public.ports.length > 0) ?? false;
if (!hasPublicPorts(serviceArgs)) throw new Error("Add public ports to use nodes.loadBalancer"); Type guard
function exposesPublicPorts(args: sst.aws.ServiceArgs): boolean {
return Array.isArray(args.containers) &&
args.containers.some((c) => (c.public?.ports?.length ?? 0) > 0);
} Try / catch
try {
return svc.nodes.loadBalancer;
} catch (e) {
if (e instanceof VisibleError && e.message.includes("no public ports")) return null;
throw e;
} Prevention
- Only access `nodes.loadBalancer` for services configured with `public` ports.
- For internal services, create and reference an explicit `sst.aws.LoadBalancer` component.
- Re-check `nodes` usage after switching services between public and internal.
When it happens
Trigger: On `sst deploy`, reading `nodes.loadBalancer` from a Service that has no `public` ports in its container/port config, or that uses an external ALB attachment without a managed LB.
Common situations: Teams switching a service from public to internal ports (or removing the `public` config) and forgetting downstream code still reads `nodes.loadBalancer`; internal-only services where no ALB is created.
Related errors
- You must provide the ports to expose via "loadBalancer.rules
- You must provide a container name in "loadBalancer.rules" wh
- Cannot access `nodes.loadBalancer` in dev mode.
- The ALB VPC "${albVpcId}" does not match the cluster VPC "${
- Request count scaling is only supported for http/https proto
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/5e95ea543e3dfc62.
Report an issue: GitHub.