{"record":{"id":"83d8d0912d8f3991","repo":"anomalyco/sst","slug":"bastion-instance-profile-must-be-a-name-not-an-ar","errorCode":null,"errorMessage":"Bastion instance profile must be a name, not an ARN.","messagePattern":"Bastion instance profile must be a name, not an ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/vpc.ts","lineNumber":1374,"sourceCode":"                    fromPort: 0,\n                    toPort: 0,\n                    cidrBlocks: [\"0.0.0.0/0\"],\n                  },\n                ],\n                tags: {\n                  \"sst:is-bastion-sg\": \"true\",\n                },\n              },\n              { parent: self },\n            ),\n          );\n\n          const instanceProfile = output(\n            bastion.instanceProfileName,\n          ).apply((instanceProfileName) => {\n            if (instanceProfileName) {\n              if (instanceProfileName.startsWith(\"arn:\")) {\n                throw new VisibleError(\n                  \"Bastion instance profile must be a name, not an ARN.\",\n                );\n              }\n\n              return iam.InstanceProfile.get(\n                `${name}BastionProfile`,\n                instanceProfileName,\n                {},\n                { parent: self },\n              );\n            }\n\n            const role = new iam.Role(\n              `${name}BastionRole`,\n              {\n                assumeRolePolicy: iam.getPolicyDocumentOutput({\n                  statements: [\n                    {","sourceCodeStart":1356,"sourceCodeEnd":1392,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/vpc.ts#L1356-L1392","documentation":"Thrown in createBastion when `bastion.instanceProfileName` is given as an ARN (starts with \"arn:\") instead of the profile's plain name. The component calls iam.InstanceProfile.get(name, ...) which expects the profile NAME, so ARNs are explicitly rejected with a clear message.","triggerScenarios":"Setting `{ bastion: { instanceProfile: \"arn:aws:iam::123456789012:instance-profile/my-profile\" } }` in the VPC config.","commonSituations":"Copying the full ARN from the IAM console instead of just the profile name; generating config from CLI output that prints ARNs.","solutions":["Use only the profile name, e.g. \"my-profile\", not the full ARN.","Extract the name from the ARN (the part after instance-profile/).","Better: reference an iam.InstanceProfile created in the same app and pass its .name output."],"exampleFix":"// before\n{ bastion: { instanceProfile: \"arn:aws:iam::123456789012:instance-profile/myBastionProfile\" } }\n// after\n{ bastion: { instanceProfile: \"myBastionProfile\" } }","handlingStrategy":"validation","validationCode":"const profile = \"arn:aws:iam::123456789012:instance-profile/myBastionProfile\";\nconst profileName = profile.includes(\"instance-profile/\")\n  ? profile.split(\"instance-profile/\")[1]\n  : profile; // pass profileName to bastion.instanceProfile","typeGuard":"const isArn = (s: string) => s.startsWith(\"arn:\");\nconst toProfileName = (s: string) => isArn(s) ? s.split(\"instance-profile/\")[1] : s;","tryCatchPattern":null,"preventionTips":["Pass iam.InstanceProfile.name outputs instead of hand-written ARNs","Strip the name from ARNs when copying from the IAM console","Add a pre-deploy lint check rejecting bastion.instanceProfile strings containing 'arn:'"],"tags":["vpc","bastion","iam","config-validation","aws"],"backgroundTag":"arn-vs-name-mismatch","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}