{"record":{"id":"b264eff6f5ab54f4","repo":"anomalyco/sst","slug":"the-provided-arn-streamarn-is-not-a-kinesis-s","errorCode":null,"errorMessage":"The provided ARN \"${streamArn}\" is not a Kinesis stream ARN.","messagePattern":"The provided ARN \"(.+?)\" is not a Kinesis stream ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/helpers/arn.ts","lineNumber":87,"sourceCode":"}\n\nexport function parseDynamoStreamArn(streamArn: string) {\n  // ie. \"arn:aws:dynamodb:us-east-1:112233445566:table/MyTable/stream/2024-02-25T23:17:55.264\"\n  const parts = streamArn.split(\":\");\n  const tableName = parts[5]?.split(\"/\")[1];\n  if (parts[0] !== \"arn\" || parts[2] !== \"dynamodb\" || !tableName)\n    throw new VisibleError(\n      `The provided ARN \"${streamArn}\" is not a DynamoDB stream ARN.`,\n    );\n  return { tableName };\n}\n\nexport function parseKinesisStreamArn(streamArn: string) {\n  // ie. \"arn:aws:kinesis:us-east-1:123456789012:stream/MyStream\";\n  const parts = streamArn.split(\":\");\n  const streamName = parts[5]?.split(\"/\")[1];\n  if (parts[0] !== \"arn\" || parts[2] !== \"kinesis\" || !streamName)\n    throw new VisibleError(\n      `The provided ARN \"${streamArn}\" is not a Kinesis stream ARN.`,\n    );\n  return { streamName };\n}\n\nexport function parseEventBusArn(arn: string) {\n  // arn:aws:events:region:account-id:event-bus/bus-name\n  const busName = arn.split(\"/\")[1];\n  if (!arn.startsWith(\"arn:\") || !busName)\n    throw new VisibleError(\n      `The provided ARN \"${arn}\" is not a EventBridge event bus ARN.`,\n    );\n  return { busName };\n}\n\nexport function parseRoleArn(arn: string) {\n  // arn:aws:iam::123456789012:role/MyRole\n  const roleName = arn.split(\"/\")[1];","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/helpers/arn.ts#L69-L105","documentation":"parseKinesisStreamArn validates a Kinesis data stream ARN (arn:aws:kinesis:region:account-id:stream/MyStream) and extracts the stream name. It throws a VisibleError when the service segment is not 'kinesis' or no stream name follows 'stream/'.","triggerScenarios":"Subscribing a function to a Kinesis stream by ARN where the string is a stream name, a Firehose delivery stream ARN, or a truncated ARN.","commonSituations":"Passing just the stream name, using a Kinesis Data Firehose or Data Analytics ARN (wrong service), missing the stream/ prefix segment.","solutions":["Use the full form arn:aws:kinesis:region:account-id:stream/stream-name","Copy the ARN from the Kinesis console stream details page","If using Firehose, note its ARN has delivery-stream/ and is not accepted here"],"exampleFix":"// before\nparseKinesisStreamArn(\"my-stream\");\n// after\nparseKinesisStreamArn(\"arn:aws:kinesis:us-east-1:123456789012:stream/my-stream\");","handlingStrategy":"validation","validationCode":"const KINESIS_ARN = /^arn:aws[a-zA-Z-]*:kinesis:[^:]+:\\d{12}:stream\\/[^/]+$/;\nif (!KINESIS_ARN.test(arn)) throw new Error(`Not a Kinesis stream ARN: ${arn}`);","typeGuard":"function isKinesisStreamArn(v: string): boolean {\n  return /^arn:aws[a-zA-Z-]*:kinesis:[^:]+:\\d{12}:stream\\/[^/]+$/.test(v);\n}","tryCatchPattern":"try {\n  const { streamName } = parseKinesisStreamArn(streamArn);\n} catch (e) {\n  throw new Error(`Failed to parse Kinesis stream ARN \"${streamArn}\": ${(e as Error).message}`);\n}","preventionTips":["Ensure the ARN service segment is kinesis (not firehose or analytics)","Copy the ARN from the Kinesis stream details page, not the name","Use sst.aws.KinesisStream.arn when the stream is managed by SST"],"tags":["arn","kinesis","validation","sst"],"backgroundTag":"invalid-arn-format","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}