{"record":{"id":"e81f54f32cdac0d5","repo":"anomalyco/sst","slug":"the-provided-arn-arn-is-not-an-sns-topic-arn","errorCode":null,"errorMessage":"The provided ARN \"${arn}\" is not an SNS Topic ARN.","messagePattern":"The provided ARN \"(.+?)\" is not an SNS Topic ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/helpers/arn.ts","lineNumber":42,"sourceCode":"  };\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(\":\");\n  if (arnStr !== \"arn\" || !queueName)\n    throw new VisibleError(\n      `The provided ARN \"${arn}\" is not an SQS Queue ARN.`,\n    );\n  return {\n    queueName,\n    queueUrl: `https://sqs.${region}.amazonaws.com/${accountId}/${queueName}`,\n  };\n}\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/helpers/arn.ts#L24-L60","documentation":"parseTopicArn validates that a string is an SNS topic ARN (arn:aws:sns:region:account-id:topic-name). It throws a VisibleError when the string lacks the 'arn:' prefix or a topic-name segment at index 5.","triggerScenarios":"Subscribing a function or queue to an SNS topic via ARN where the string is a topic name, a URL, or a truncated ARN.","commonSituations":"Passing just the topic name, copying an SNS subscription endpoint instead of the topic ARN, missing region/account segments.","solutions":["Use the full form arn:aws:sns:region:account-id:topic-name","If you have the topic name, construct the ARN with region and account ID","Verify the ARN in the AWS console (SNS > Topics) and copy it exactly"],"exampleFix":"// before\nparseTopicArn(\"my-topic\");\n// after\nparseTopicArn(\"arn:aws:sns:us-east-1:123456789012:my-topic\");","handlingStrategy":"validation","validationCode":"const TOPIC_ARN = /^arn:aws[a-zA-Z-]*:sns:[^:]+:\\d{12}:.+$/;\nif (!TOPIC_ARN.test(arn)) throw new Error(`Not an SNS topic ARN: ${arn}`);","typeGuard":"function isTopicArn(v: string): boolean {\n  return /^arn:aws[a-zA-Z-]*:sns:[^:]+:\\d{12}:.+$/.test(v);\n}","tryCatchPattern":"try {\n  const { topicName } = parseTopicArn(arn);\n} catch (e) {\n  throw new Error(`Failed to parse SNS topic ARN \"${arn}\": ${(e as Error).message}`);\n}","preventionTips":["Use sst.sns.Topic.arn from a component reference rather than hand-built strings","Validate region and account ID segments when constructing ARNs manually","Check the service segment is sns, not sqs or events"],"tags":["arn","sns","validation","sst"],"backgroundTag":"invalid-arn-format","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}