{"record":{"id":"0793865a0f8da53c","repo":"gatsbyjs/gatsby","slug":"invalid-bucket-process-env-s3-bucket","errorCode":null,"errorMessage":"invalid bucket ${process.env.S3_BUCKET}","messagePattern":"invalid bucket (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/gatsby-transformer-screenshot/lambda/screenshot.js","lineNumber":61,"sourceCode":"  }\n\n  async putFile(fileBuffer) {\n    await fsPromises.writeFile(this.fileUrl, fileBuffer)\n    this.expires = undefined\n    return { url: this.fileUrl, expires: this.expires }\n  }\n}\n\n/**\n * put / get a screenshot to S3\n */\nclass S3Screenshot extends Screenshot {\n  constructor(opts) {\n    super(opts)\n    // async jiggery pokery\n    return (async () => {\n      const region = await s3GetBucketLocation(process.env.S3_BUCKET)\n      if (!region) throw new Error(`invalid bucket ${process.env.S3_BUCKET}`)\n      this.fileUrl = `https://s3-${region}.amazonaws.com/${process.env.S3_BUCKET}/${this.key}`\n      return this // when done\n    })()\n  }\n\n  async getFile() {\n    const meta = await s3HeadObject(this.key)\n    if (meta && meta.Expiration) {\n      this.expires = getDateFromExpiration(meta.Expiration)\n      const now = new Date()\n      if (now < this.expires) {\n        return { url: this.fileUrl, expires: this.expires }\n      }\n    }\n    return false\n  }\n\n  async putFile(fileBuffer) {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-transformer-screenshot/lambda/screenshot.js#L43-L79","documentation":"Thrown inside the S3Screenshot constructor in the gatsby-transformer-screenshot Lambda. The constructor calls s3GetBucketLocation(S3_BUCKET) to resolve the AWS region for building the public file URL. If that call resolves to a falsy value (null), the bucket name is invalid, inaccessible, or the AWS credentials lack permission to inspect it.","triggerScenarios":"The Lambda starts, reads process.env.S3_BUCKET, calls s3.getBucketLocation via the AWS SDK, and the promise resolves null — either because the SDK returned an error (which s3GetBucketLocation swallows by resolving null) or the bucket does not exist in the configured region. The constructor then rejects with this error.","commonSituations":"S3_BUCKET env var is misspelled, points to a bucket in a different AWS account, the Lambda's IAM role lacks s3:GetBucketLocation permission, the bucket was deleted, or AWS credentials are not configured (defaulting to a region where the bucket doesn't exist).","solutions":["Verify the S3_BUCKET env var matches an existing bucket: run `aws s3 ls s3://BUCKET_NAME` with the same credentials the Lambda uses.","Ensure the Lambda execution role has s3:GetBucketLocation and s3:PutObject permissions on the target bucket.","Confirm AWS_REGION/AWS_DEFAULT_REGION is set correctly for the bucket's region.","Check that AWS credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) are valid and not expired."],"exampleFix":"// before\nS3_BUCKET=my-typo-bucket\n\n// after — verify bucket exists and IAM permits access\naws s3 ls s3://my-correct-bucket\n# set env: S3_BUCKET=my-correct-bucket","handlingStrategy":"validation","validationCode":"// Pre-flight check before Lambda handles a request\nconst AWS = require('aws-sdk')\n\nasync function validateS3Bucket(bucketName) {\n  const s3 = new AWS.S3()\n  try {\n    const data = await s3.getBucketLocation({ Bucket: bucketName }).promise()\n    if (!data.LocationConstraint && data.LocationConstraint !== '') return false\n    return true\n  } catch {\n    return false\n  }\n}\n\n// At cold start:\nif (!await validateS3Bucket(process.env.S3_BUCKET)) {\n  console.error('S3_BUCKET is invalid or inaccessible')\n}","typeGuard":null,"tryCatchPattern":"// Wrap the S3Screenshot constructor usage\ntry {\n  const screenshot = await new S3Screenshot(opts)\n  // use screenshot...\n} catch (e) {\n  if (e.message.includes('invalid bucket')) {\n    // fall back to local FS or report configuration error\n    console.error('S3 bucket misconfigured:', e.message)\n  } else {\n    throw e\n  }\n}","preventionTips":["Set up a Lambda health check that validates S3 access on cold start.","Use Infrastructure-as-Code (CloudFormation/Terraform) to ensure the bucket exists before deploying.","Store the bucket name in AWS Systems Manager Parameter Store for consistency.","Test IAM permissions in staging before promoting to production."],"tags":["s3","aws","lambda","environment-variables","iam","gatsby-transformer-screenshot"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}