anomalyco/sst · error · VisibleError

You must provide the ports to expose via "public.ports".

Error message

You must provide the ports to expose via "public.ports".

What it means

When `public` is provided on a Service, SST uses a load balancer and needs to know which ports to expose. If `public.ports` is missing or an empty array, normalizePublic throws because the LB would have no listeners.

Source

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

        cpuUtilization: v?.cpuUtilization ?? 70,
        memoryUtilization: v?.memoryUtilization ?? 70,
      }));
    }

    function normalizeLogging() {
      return output(args.logging).apply((logging) => ({
        ...logging,
        retention: logging?.retention ?? "1 month",
      }));
    }

    function normalizePublic() {
      if (!args.public) return;

      const ports = output(args.public).apply((pub) => {
        // validate ports
        if (!pub.ports || pub.ports.length === 0)
          throw new VisibleError(
            `You must provide the ports to expose via "public.ports".`,
          );

        // parse protocols and ports
        const ports = pub.ports.map((v) => {
          const listenParts = v.listen.split("/");
          const forwardParts = v.forward ? v.forward.split("/") : listenParts;
          return {
            listenPort: parseInt(listenParts[0]),
            listenProtocol: listenParts[1],
            forwardPort: parseInt(forwardParts[0]),
            forwardProtocol: forwardParts[1],
          };
        });

        // validate protocols are consistent
        const appProtocols = ports.filter(
          (port) =>

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Add at least one entry to `public.ports`, e.g. `ports: [{ listen: "80/http" }]`
  2. If the service should be private, remove the `public` block entirely
  3. Ensure ports entries include both listen and forward specifiers

Example fix

// before
new sst.aws.Service("Api", { public: {} });
// after
new sst.aws.Service("Api", {
  public: { ports: [{ listen: "80/http", forward: "8080/http" }] },
});
Defensive patterns

Strategy: validation

Validate before calling

if (args.public && (!args.public.ports || args.public.ports.length === 0)) {
  throw new Error('public block requires at least one entry in "ports"');
}

Prevention

When it happens

Trigger: Passing `public: {}` or `public: { domain: ... }` without `ports`, or `ports: []`, to `sst.aws.Service`.

Common situations: Intending to make the service public but only configuring domain/TLS; copying a private-service example and adding an empty `public` block.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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