anomalyco/sst · error · VisibleError
The provided ARN "${arn}" is not an S3 bucket ARN.
Error message
The provided ARN "${arn}" is not an S3 bucket ARN. What it means
parseBucketArn validates that a string is an S3 bucket ARN of the form arn:aws:s3:::bucket-name. It throws a VisibleError when the string lacks the 'arn:' prefix or the bucket-name segment at index 5.
Source
Thrown at platform/src/components/aws/helpers/arn.ts:32
export function splitQualifiedFunctionArn(arn: string) {
// Unqualified: arn:aws:lambda:region:account-id:function:function-name (7 parts)
// Qualified: arn:aws:lambda:region:account-id:function:function-name:alias-or-version (8 parts)
const parts = arn.split(":");
if (parts.length <= 7) {
return { unqualifiedArn: arn, qualifier: undefined };
}
return {
unqualifiedArn: parts.slice(0, 7).join(":"),
qualifier: parts[7],
};
}
export function parseBucketArn(arn: string) {
// arn:aws:s3:::bucket-name
const bucketName = arn.split(":")[5];
if (!arn.startsWith("arn:") || !bucketName)
throw new VisibleError(
`The provided ARN "${arn}" is not an S3 bucket ARN.`,
);
return { bucketName };
}
export function parseTopicArn(arn: string) {
// arn:aws:sns:region:account-id:topic-name
const topicName = arn.split(":")[5];
if (!arn.startsWith("arn:") || !topicName)
throw new VisibleError(
`The provided ARN "${arn}" is not an SNS Topic ARN.`,
);
return { topicName };
}
export function parseQueueArn(arn: string) {
// arn:aws:sqs:region:account-id:queue-name
const [arnStr, , , region, accountId, queueName] = arn.split(":");View on GitHub (pinned to a0bd20f762)
Solutions
- Use the exact form arn:aws:s3:::bucket-name (region and account segments empty)
- If you only have the bucket name, build the ARN as `arn:aws:s3:::${bucketName}`
- Strip schemes like s3:// and trailing paths before passing
Example fix
// before
parseBucketArn("s3://my-bucket");
// after
parseBucketArn("arn:aws:s3:::my-bucket"); Defensive patterns
Strategy: validation
Validate before calling
const BUCKET_ARN = /^arn:aws:s3:::[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;
if (!BUCKET_ARN.test(arn)) throw new Error(`Not an S3 bucket ARN: ${arn}`); Type guard
function isBucketArn(v: string): boolean {
return /^arn:aws:s3:::[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(v);
} Try / catch
try {
const { bucketName } = parseBucketArn(arn);
} catch (e) {
throw new Error(`Failed to parse S3 bucket ARN "${arn}": ${(e as Error).message}`);
} Prevention
- Strip s3:// prefixes before passing bucket references
- Remember S3 ARNs have empty region and account fields
- Prefer passing the SST Bucket component instead of raw ARNs
When it happens
Trigger: Passing a bucket name or bucket URL to an API expecting a bucket ARN, e.g. s3 notifications or EventBus bucket sources resolved via bucketName().
Common situations: Using 's3://bucket-name' or a website URL instead of the ARN, forgetting that S3 ARNs have empty region and account segments, referencing a folder-style ARN with a trailing slash.
Related errors
- The provided ARN "${arn}" is not a Lambda function ARN.
- The provided ARN "${arn}" is not an SNS Topic ARN.
- The provided ARN "${arn}" is not an SQS Queue ARN.
- The provided ARN "${arn}" is not a DynamoDB table ARN.
- The provided ARN "${streamArn}" is not a DynamoDB stream ARN
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/7a7f3301a2826c24.
Report an issue: GitHub.