{"record":{"id":"fa60165421da44d8","repo":"apache/beam","slug":"metadata-operation-failed-blobstoragefilesystem","errorCode":null,"errorMessage":"Metadata operation failed","messagePattern":"Metadata operation failed","errorType":"exception","errorClass":"BeamIOError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/azure/blobstoragefilesystem.py","lineNumber":299,"sourceCode":"\n  def metadata(self, path):\n    \"\"\"Fetch metadata fields of a file on the FileSystem.\n\n    Args:\n      path: string path of a file.\n\n    Returns:\n      :class:`~apache_beam.io.filesystem.FileMetadata`.\n\n    Raises:\n      ``BeamIOError``: if path isn't a file or doesn't exist.\n    \"\"\"\n    try:\n      file_metadata = self._blobstorageIO()._status(path)\n      return FileMetadata(\n          path, file_metadata['size'], file_metadata['last_updated'])\n    except Exception as e:  # pylint: disable=broad-except\n      raise BeamIOError(\"Metadata operation failed\", {path: e})\n\n  def delete(self, paths):\n    \"\"\"Deletes files or directories at the provided paths.\n    Directories will be deleted recursively.\n\n    Args:\n      paths: list of paths that give the file objects to be deleted\n\n    Raises:\n      ``BeamIOError``: if any of the delete operations fail\n    \"\"\"\n    results = self._blobstorageIO().delete_paths(paths)\n    # Retrieve exceptions.\n    exceptions = {\n        path: error\n        for (path, error) in results.items() if error is not None\n    }\n","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/azure/blobstoragefilesystem.py#L281-L317","documentation":"BlobStorageFileSystem.metadata() fetches size and last_updated via BlobStorageIO._status() and re-raises any exception as BeamIOError('Metadata operation failed', {path: e}). It fails if the blob does not exist or the Azure SDK call fails, and also if the returned status dict lacks the expected 'size'/'last_updated' keys.","triggerScenarios":"Calling fs.metadata(path) on a missing blob, with bad credentials, or when _status returns a dict without 'size' or 'last_updated' (KeyError is also caught and wrapped).","commonSituations":"Listing-derived paths that were deleted before metadata fetch; service changes/SDK version drift making _status fields absent; auth misconfiguration; using it on directory-style prefixes.","solutions":["Check fs.exists(path) before fetching metadata","Inspect BeamIOError.exception_details[path] for the underlying KeyError/Azure exception","Pin compatible azure-storage-blob versions so _status returns the expected fields","Verify credentials and container read permissions"],"exampleFix":"// before\nmeta = fs.metadata(path)\n// after\ntry:\n    meta = fs.metadata(path)\nexcept BeamIOError as e:\n    logging.error(f\"metadata failed for {path}: {e.exception_details}\")\n    meta = None","handlingStrategy":"try-catch","validationCode":"if not fs.exists(path):\n    raise FileNotFoundError(f\"no such blob: {path}\")","typeGuard":null,"tryCatchPattern":"try:\n    meta = fs.metadata(path)\nexcept BeamIOError as e:\n    logging.error(\"metadata failed for %s: %s\", path, e.exception_details)\n    meta = None  # handle missing metadata explicitly downstream","preventionTips":["Handle the case where size/last_updated keys may be missing in the wrapped cause","Pin azure-storage-blob to the version compatible with your apache-beam release","Validate credentials before metadata-heavy operations","Pre-check existence for paths that may have been deleted"],"tags":["python","apache-beam","azure-blob-storage","filesystem-io","error-wrapping"],"backgroundTag":"file-read-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}