{"record":{"id":"7a7f3301a2826c24","repo":"anomalyco/sst","slug":"the-provided-arn-arn-is-not-an-s3-bucket-arn","errorCode":null,"errorMessage":"The provided ARN \"${arn}\" is not an S3 bucket ARN.","messagePattern":"The provided ARN \"(.+?)\" is not an S3 bucket ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/helpers/arn.ts","lineNumber":32,"sourceCode":"export function splitQualifiedFunctionArn(arn: string) {\n  // Unqualified: arn:aws:lambda:region:account-id:function:function-name (7 parts)\n  // Qualified:   arn:aws:lambda:region:account-id:function:function-name:alias-or-version (8 parts)\n  const parts = arn.split(\":\");\n  if (parts.length <= 7) {\n    return { unqualifiedArn: arn, qualifier: undefined };\n  }\n  return {\n    unqualifiedArn: parts.slice(0, 7).join(\":\"),\n    qualifier: parts[7],\n  };\n}\n\n\nexport function parseBucketArn(arn: string) {\n  // arn:aws:s3:::bucket-name\n  const bucketName = arn.split(\":\")[5];\n  if (!arn.startsWith(\"arn:\") || !bucketName)\n    throw new VisibleError(\n      `The provided ARN \"${arn}\" is not an S3 bucket ARN.`,\n    );\n  return { bucketName };\n}\n\nexport function parseTopicArn(arn: string) {\n  // arn:aws:sns:region:account-id:topic-name\n  const topicName = arn.split(\":\")[5];\n  if (!arn.startsWith(\"arn:\") || !topicName)\n    throw new VisibleError(\n      `The provided ARN \"${arn}\" is not an SNS Topic ARN.`,\n    );\n  return { topicName };\n}\n\nexport function parseQueueArn(arn: string) {\n  // arn:aws:sqs:region:account-id:queue-name\n  const [arnStr, , , region, accountId, queueName] = arn.split(\":\");","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/helpers/arn.ts#L14-L50","documentation":"parseBucketArn validates that a string is an S3 bucket ARN of the form arn:aws:s3:::bucket-name. It throws a VisibleError when the string lacks the 'arn:' prefix or the bucket-name segment at index 5.","triggerScenarios":"Passing a bucket name or bucket URL to an API expecting a bucket ARN, e.g. s3 notifications or EventBus bucket sources resolved via bucketName().","commonSituations":"Using 's3://bucket-name' or a website URL instead of the ARN, forgetting that S3 ARNs have empty region and account segments, referencing a folder-style ARN with a trailing slash.","solutions":["Use the exact form arn:aws:s3:::bucket-name (region and account segments empty)","If you only have the bucket name, build the ARN as `arn:aws:s3:::${bucketName}`","Strip schemes like s3:// and trailing paths before passing"],"exampleFix":"// before\nparseBucketArn(\"s3://my-bucket\");\n// after\nparseBucketArn(\"arn:aws:s3:::my-bucket\");","handlingStrategy":"validation","validationCode":"const BUCKET_ARN = /^arn:aws:s3:::[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nif (!BUCKET_ARN.test(arn)) throw new Error(`Not an S3 bucket ARN: ${arn}`);","typeGuard":"function isBucketArn(v: string): boolean {\n  return /^arn:aws:s3:::[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(v);\n}","tryCatchPattern":"try {\n  const { bucketName } = parseBucketArn(arn);\n} catch (e) {\n  throw new Error(`Failed to parse S3 bucket ARN \"${arn}\": ${(e as Error).message}`);\n}","preventionTips":["Strip s3:// prefixes before passing bucket references","Remember S3 ARNs have empty region and account fields","Prefer passing the SST Bucket component instead of raw ARNs"],"tags":["arn","s3","validation","sst"],"backgroundTag":"invalid-arn-format","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}