anomalyco/sst · error · VisibleError

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

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.

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)

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.