{"record":{"id":"5f4047eecd884b18","repo":"anomalyco/sst","slug":"the-provided-arn-arn-is-not-a-dynamodb-table","errorCode":null,"errorMessage":"The provided ARN \"${arn}\" is not a DynamoDB table ARN.","messagePattern":"The provided ARN \"(.+?)\" is not a DynamoDB table ARN\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/helpers/arn.ts","lineNumber":65,"sourceCode":"\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\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\";","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/helpers/arn.ts#L47-L83","documentation":"parseDynamoArn validates a DynamoDB table ARN (arn:aws:dynamodb:region:account-id:table/table-name) and extracts the table name. It throws a VisibleError when the string lacks 'arn:' or has no '/'-delimited table name.","triggerScenarios":"Creating an AppSync data source from a table ARN where the string is a table name or a stream ARN without the table/table-name path.","commonSituations":"Passing just the table name, passing a stream ARN where a table ARN is expected, missing region/account segments.","solutions":["Use the full form arn:aws:dynamodb:region:account-id:table/table-name","If you only have the table name, build the ARN with region and account ID","For streams use parseDynamoStreamArn instead of parseDynamoArn"],"exampleFix":"// before\nparseDynamoArn(\"my-table\");\n// after\nparseDynamoArn(\"arn:aws:dynamodb:us-east-1:123456789012:table/my-table\");","handlingStrategy":"validation","validationCode":"const TABLE_ARN = /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\\d{12}:table\\/[^/]+$/;\nif (!TABLE_ARN.test(arn)) throw new Error(`Not a DynamoDB table ARN: ${arn}`);","typeGuard":"function isDynamoTableArn(v: string): boolean {\n  return /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\\d{12}:table\\/[^/]+$/.test(v);\n}","tryCatchPattern":"try {\n  const { tableName } = parseDynamoArn(arn);\n} catch (e) {\n  throw new Error(`Failed to parse DynamoDB table ARN \"${arn}\": ${(e as Error).message}`);\n}","preventionTips":["Use table ARNs (table/Name), not stream ARNs (table/Name/stream/...) where a table is expected","Reference sst.aws.Dynamo.arn when the table is managed by SST","Keep table names free of '/' characters"],"tags":["arn","dynamodb","validation","sst"],"backgroundTag":"invalid-arn-format","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}