{"record":{"id":"cc249f6c96572e10","repo":"anomalyco/sst","slug":"you-must-provide-a-container-name-in-each-rule-w","errorCode":null,"errorMessage":"You must provide a \"container\" name in each rule when there is more than one container in Service \"${name}\".","messagePattern":"You must provide a \"container\" name in each rule when there is more than one container in Service \"(.+?)\"\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/service.ts","lineNumber":2628,"sourceCode":"    function createAlbTargetsAndEntries(\n      attachment: NonNullable<typeof albAttachment>,\n    ) {\n      const rules = attachment.rules;\n      const health = attachment.health ?? {};\n\n      if (rules.length === 0) {\n        throw new VisibleError(\n          `You must provide at least one rule in \"loadBalancer.rules\" when using an external ALB in Service \"${name}\".`,\n        );\n      }\n\n      // Validate container names (no resources created here)\n      containers.apply((ctrs) => {\n        const containerNames = new Set(ctrs.map((c) => c.name));\n        if (ctrs.length > 1) {\n          for (const rule of rules) {\n            if (!rule.container) {\n              throw new VisibleError(\n                `You must provide a \"container\" name in each rule when there is more than one container in Service \"${name}\".`,\n              );\n            }\n          }\n        }\n        for (const rule of rules) {\n          const cn = rule.container ?? ctrs[0].name;\n          if (!containerNames.has(cn)) {\n            throw new VisibleError(\n              `Container \"${cn}\" in \"loadBalancer.rules\" does not match any container in Service \"${name}\". Available: ${[...containerNames].join(\", \")}.`,\n            );\n          }\n        }\n      });\n\n      // Create target groups in a plain loop (no apply)\n      const targets: Record<string, lb.TargetGroup> = {};\n      const rawEntries: {","sourceCodeStart":2610,"sourceCodeEnd":2646,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/service.ts#L2610-L2646","documentation":"With a single container SST can infer the target container, but with multiple containers each ALB rule must name which container receives the traffic. Ambiguity would otherwise route traffic unpredictably, so the constructor rejects rules missing a container name.","triggerScenarios":"A Service with two or more containers plus an external ALB attachment where one or more rules omit the container field.","commonSituations":"Adding a sidecar (e.g. envoy, datadog agent) to an existing single-container service and forgetting to update the rules; copy-pasting rules from a single-container example.","solutions":["Add container: \"<name>\" to every rule, matching the container's name","Reduce to a single container if the extra one isn't needed","Ensure sidecars are defined without LB rules and only the public-facing container is referenced"],"exampleFix":"// before\nrules: [{ listen: \"443/https\", conditions: { path: \"/*\" } }]\n// after\nrules: [{ listen: \"443/https\", container: \"app\", conditions: { path: \"/*\" } }]","handlingStrategy":"validation","validationCode":"if (config.containers.length > 1)\n  for (const r of attachment.rules)\n    if (!r.container) throw new Error(`rule for ${r.listen} must specify container`);","typeGuard":"const ruleHasContainer = (r: { container?: string }) => typeof r.container === \"string\" && r.container.length > 0;","tryCatchPattern":"null","preventionTips":["When adding a sidecar container, audit existing LB rules and name the target container","Always specify container explicitly, even with one container","Keep container names in a shared constant module"],"tags":["load-balancer","containers","validation"],"backgroundTag":"missing-required-config","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}