Bug
S3Client constructor accepts an optional profile parameter but no caller ever passes it. Every instantiation in the deploy code only passes region:
const s3 = new S3Client(region) // profile defaults to 'default'The constructor defaults to 'default' when no profile is provided:
constructor(region: string = 'us-east-1', profile?: string) {
this.profile = profile || 'default'This means resolveProfileCredentialsSync() skips env vars when AWS_PROFILE is set to anything other than 'default':
if (envAccessKey && envSecretKey && (!envProfile || envProfile === this.profile)) {
// this.profile is 'default', envProfile is 'eliinova' — mismatch, skippedAnd then tries to read the [default] profile from ~/.aws/credentials instead of the one specified by AWS_PROFILE.
Expected Behavior
S3Client should respect AWS_PROFILE env var when no explicit profile is passed.
Fix
In the constructor, default to process.env.AWS_PROFILE before falling back to 'default':
this.profile = profile || process.env.AWS_PROFILE || 'default'Affected Files
packages/ts-cloud/src/aws/s3.ts(constructor line 75)- All callers in
packages/ts-cloud/src/deploy/static-site.tsandstatic-site-external-dns.ts
Impact
Any project using a non-default AWS profile for deployment gets AccessDenied on S3 operations.