{"record":{"id":"bee23b3d6b18b46d","repo":"anomalyco/sst","slug":"the-provided-arn-streamarn-is-not-a-dynamodb","errorCode":null,"errorMessage":"The provided ARN \"${streamArn}\" is not a DynamoDB stream ARN.","messagePattern":"The provided ARN \"(.+?)\" is not a DynamoDB stream ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/helpers/arn.ts","lineNumber":76,"sourceCode":"  };\n}\n\nexport function parseDynamoArn(arn: string) {\n  // arn:aws:dynamodb:region:account-id:table/table-name\n  const tableName = arn.split(\"/\")[1];\n  if (!arn.startsWith(\"arn:\") || !tableName)\n    throw new VisibleError(\n      `The provided ARN \"${arn}\" is not a DynamoDB table ARN.`,\n    );\n  return { tableName };\n}\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","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/helpers/arn.ts#L58-L94","documentation":"parseDynamoStreamArn validates a DynamoDB stream ARN, which must contain the dynamodb service and a table/.../stream/... path. It throws a VisibleError when the service segment is not 'dynamodb' or no table name can be extracted.","triggerScenarios":"Subscribing a function to a DynamoDB stream where the string is a table ARN without the stream segment, or an ARN from another service.","commonSituations":"Passing the table ARN instead of the stream ARN, stream not enabled on the table so only the table ARN exists, copying an ARN from a different service.","solutions":["Use the full stream ARN: arn:aws:dynamodb:region:account-id:table/MyTable/stream/<timestamp>","Enable streams on the DynamoDB table and copy the Latest stream ARN from the console","If subscribing to the table rather than its stream, use the table-based API instead"],"exampleFix":"// before\nparseDynamoStreamArn(\"arn:aws:dynamodb:us-east-1:123456789012:table/MyTable\");\n// after\nparseDynamoStreamArn(\"arn:aws:dynamodb:us-east-1:123456789012:table/MyTable/stream/2024-02-25T23:17:55.264\");","handlingStrategy":"validation","validationCode":"const STREAM_ARN = /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\\d{12}:table\\/[^/]+\\/stream\\/\\S+$/;\nif (!STREAM_ARN.test(arn)) throw new Error(`Not a DynamoDB stream ARN: ${arn}`);","typeGuard":"function isDynamoStreamArn(v: string): boolean {\n  return /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\\d{12}:table\\/[^/]+\\/stream\\/\\S+$/.test(v);\n}","tryCatchPattern":"try {\n  const { tableName } = parseDynamoStreamArn(streamArn);\n} catch (e) {\n  throw new Error(`Failed to parse DynamoDB stream ARN \"${streamArn}\": ${(e as Error).message}`);\n}","preventionTips":["Confirm streams are enabled on the table and copy the Latest stream ARN","Note stream ARNs end with a timestamp segment after stream/","Reference Dynamo.streamArn from the SST component when available"],"tags":["arn","dynamodb","streams","validation","sst"],"backgroundTag":"invalid-arn-format","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}