anomalyco/sst · error · VisibleError

You must provide at least one rule in "loadBalancer.rules"…

Error message

You must provide at least one rule in "loadBalancer.rules" when using an external ALB in Service "${name}".

What it means

When a Service attaches to an external/shared ALB, SST does not create a default catch-all listener rule for you — each rule must be explicit. An attachment with an empty rules array is invalid, so the constructor throws at synth time.

Solutions

  1. Add at least one rule with listen, container, and conditions (path/query/header)
  2. If the service shouldn't be behind the ALB yet, remove the ALB attachment
  3. Comment out the attachment until rules are ready

Example fix

// before
loadBalancer: { external: alb, rules: [] }
// after
loadBalancer: { external: alb, rules: [{ listen: "443/https", container: "app", conditions: { path: "/*" } }] }
Defensive patterns

Strategy: validation

Validate before calling

if (attachment.external && (!attachment.rules || attachment.rules.length === 0))
  throw new Error("external ALB attachment requires at least one rule");

Type guard

const hasRules = (a: { rules?: unknown[] }) => Array.isArray(a.rules) && a.rules.length > 0;

Try / catch

try {
  new sst.aws.Service(name, { loadBalancer: { external: alb, rules } });
} catch (e) {
  if (String(e).includes('at least one rule')) throw new Error(`Service ${name}: define loadBalancer.rules when using an external ALB`);
  throw e;
}

Prevention

When it happens

Trigger: Creating a Service with loadBalancer pointing at an existing ALB (albAttachment) but leaving rules: [] or omitting rules entirely.

Common situations: Scaffolding a service and planning to add rules later; assuming internal ALB defaults apply to external ALBs too; converting a self-managed-LB service to a shared ALB without porting the rules.

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/9a235b89f5b7851d. Report an issue: GitHub.

Appendix: source

Thrown at platform/src/components/aws/service.ts:2617

      if (
        !loadBalancer ||
        typeof loadBalancer !== "object" ||
        !("instance" in loadBalancer) ||
        !(loadBalancer.instance instanceof Alb)
      ) {
        return undefined;
      }
      return loadBalancer;
    }

    function createAlbTargetsAndEntries(
      attachment: NonNullable<typeof albAttachment>,
    ) {
      const rules = attachment.rules;
      const health = attachment.health ?? {};

      if (rules.length === 0) {
        throw new VisibleError(
          `You must provide at least one rule in "loadBalancer.rules" when using an external ALB in Service "${name}".`,
        );
      }

      // Validate container names (no resources created here)
      containers.apply((ctrs) => {
        const containerNames = new Set(ctrs.map((c) => c.name));
        if (ctrs.length > 1) {
          for (const rule of rules) {
            if (!rule.container) {
              throw new VisibleError(
                `You must provide a "container" name in each rule when there is more than one container in Service "${name}".`,
              );
            }
          }
        }
        for (const rule of rules) {
          const cn = rule.container ?? ctrs[0].name;

View on GitHub (pinned to a0bd20f762)