anomalyco/sst · error · VisibleError
The provided ARN "${streamArn}" is not a DynamoDB stream ARN
Error message
The provided ARN "${streamArn}" is not a DynamoDB stream ARN. What it means
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.
Source
Thrown at platform/src/components/aws/helpers/arn.ts:76
};
}
export function parseDynamoArn(arn: string) {
// arn:aws:dynamodb:region:account-id:table/table-name
const tableName = arn.split("/")[1];
if (!arn.startsWith("arn:") || !tableName)
throw new VisibleError(
`The provided ARN "${arn}" is not a DynamoDB table ARN.`,
);
return { tableName };
}
export function parseDynamoStreamArn(streamArn: string) {
// ie. "arn:aws:dynamodb:us-east-1:112233445566:table/MyTable/stream/2024-02-25T23:17:55.264"
const parts = streamArn.split(":");
const tableName = parts[5]?.split("/")[1];
if (parts[0] !== "arn" || parts[2] !== "dynamodb" || !tableName)
throw new VisibleError(
`The provided ARN "${streamArn}" is not a DynamoDB stream ARN.`,
);
return { tableName };
}
export function parseKinesisStreamArn(streamArn: string) {
// ie. "arn:aws:kinesis:us-east-1:123456789012:stream/MyStream";
const parts = streamArn.split(":");
const streamName = parts[5]?.split("/")[1];
if (parts[0] !== "arn" || parts[2] !== "kinesis" || !streamName)
throw new VisibleError(
`The provided ARN "${streamArn}" is not a Kinesis stream ARN.`,
);
return { streamName };
}
export function parseEventBusArn(arn: string) {
// arn:aws:events:region:account-id:event-bus/bus-nameView on GitHub (pinned to a0bd20f762)
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
Example fix
// before
parseDynamoStreamArn("arn:aws:dynamodb:us-east-1:123456789012:table/MyTable");
// after
parseDynamoStreamArn("arn:aws:dynamodb:us-east-1:123456789012:table/MyTable/stream/2024-02-25T23:17:55.264"); Defensive patterns
Strategy: validation
Validate before calling
const STREAM_ARN = /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\d{12}:table\/[^/]+\/stream\/\S+$/;
if (!STREAM_ARN.test(arn)) throw new Error(`Not a DynamoDB stream ARN: ${arn}`); Type guard
function isDynamoStreamArn(v: string): boolean {
return /^arn:aws[a-zA-Z-]*:dynamodb:[^:]+:\d{12}:table\/[^/]+\/stream\/\S+$/.test(v);
} Try / catch
try {
const { tableName } = parseDynamoStreamArn(streamArn);
} catch (e) {
throw new Error(`Failed to parse DynamoDB stream ARN "${streamArn}": ${(e as Error).message}`);
} Prevention
- 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
When it happens
Trigger: Subscribing a function to a DynamoDB stream where the string is a table ARN without the stream segment, or an ARN from another service.
Common situations: 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.
Related errors
- The provided ARN "${arn}" is not a DynamoDB table ARN.
- The provided ARN "${arn}" is not a Lambda function ARN.
- The provided ARN "${arn}" is not an S3 bucket ARN.
- The provided ARN "${arn}" is not an SNS Topic ARN.
- The provided ARN "${arn}" is not an SQS Queue ARN.
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/bee23b3d6b18b46d.
Report an issue: GitHub.