{"record":{"id":"cad3f37bfffad8cd","repo":"apache/beam","slug":"not-found-fake-client","errorCode":null,"errorMessage":"Not Found","messagePattern":"Not Found","errorType":"http","errorClass":"S3ClientError","httpStatus":404,"severity":"error","filePath":"sdks/python/apache_beam/io/aws/clients/s3/fake_client.py","lineNumber":75,"sourceCode":"    self.files = {}\n    self.list_continuation_tokens = {}\n    self.multipart_uploads = {}\n\n    # boto3 has different behavior when running some operations against a bucket\n    # that exists vs. against one that doesn't. To emulate that behavior, the\n    # mock client keeps a set of bucket names that it knows \"exist\".\n    self.known_buckets = set()\n\n  def add_file(self, f):\n    self.files[(f.bucket, f.key)] = f\n    if f.bucket not in self.known_buckets:\n      self.known_buckets.add(f.bucket)\n\n  def get_file(self, bucket, obj):\n    try:\n      return self.files[bucket, obj]\n    except:\n      raise messages.S3ClientError('Not Found', 404)\n\n  def delete_file(self, bucket, obj):\n    del self.files[(bucket, obj)]\n\n  def get_object_metadata(self, request):\n    r\"\"\"Retrieves an object's metadata.\n\n    Args:\n      request: (GetRequest) input message\n\n    Returns:\n      (Item) The response message.\n    \"\"\"\n    # TODO: Do we want to mock out a lack of credentials?\n    file_ = self.get_file(request.bucket, request.object)\n    return file_.get_metadata()\n\n  def list(self, request):","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/aws/clients/s3/fake_client.py#L57-L93","documentation":"FakeS3Client.get_file raises S3ClientError('Not Found', 404) when the requested (bucket, key) pair is not present in its in-memory file store. It is the test-double equivalent of a 404 NoSuchKey from real S3.","triggerScenarios":"Calling get_object_metadata, list, get_range, or copy against a FakeS3Client whose internal files dict lacks (bucket, obj); e.g. a file was never inserted or was deleted by delete_file.","commonSituations":"Unit tests that forgot to call create_file/put before reading; test fixtures referencing a key that was renamed; delete_file called earlier in the same test than expected.","solutions":["Insert the fake file before reading: fake_client.create_file(bucket, obj, contents)","Assert on the correct bucket/key names matching what the code under test requests","Seed the FakeS3Client with all fixture files the pipeline will touch","Wrap reads in try/except S3ClientError with a 404 check if absence is expected"],"exampleFix":"// before\nmetadata = fake_client.get_object_metadata(messages.GetObjectMetadataRequest('mybucket', 'missing.txt'))\n// after\nfake_client.create_file('mybucket', 'missing.txt', b'data')\nmetadata = fake_client.get_object_metadata(messages.GetObjectMetadataRequest('mybucket', 'missing.txt'))","handlingStrategy":"try-catch","validationCode":"if (bucket, obj) not in fake_client.files:\n    fake_client.create_file(bucket, obj, b'fixture-data')","typeGuard":null,"tryCatchPattern":"try:\n    meta = fake_client.get_object_metadata(req)\nexcept messages.S3ClientError as e:\n    if e.code == 404:\n        meta = None  # expected absence\n    else:\n        raise","preventionTips":["Seed all fixture files before the code under test runs","Use shared constants for bucket/key names between setup and assertions","Track delete_file calls in tests to avoid reads after deletes","Assert on fake_client.files contents when debugging"],"tags":["aws","s3","test-fixture","io"],"backgroundTag":"resource-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}