Problem
When passing registry="gs://bucket/feast/registry.pb" as a string to RepoConfig, Feast always creates a file-based RegistryConfig (hardcoded at repo_config.py line ~402). This ignores the URI scheme and causes FileRegistryStore to be used, which cannot handle gs:// paths — pathlib.Path("gs://...") is not treated as absolute, leading to IsADirectoryError at runtime.
The RegistryConfig docstring states:
If registry_type is 'file', then can be a local path, or remote object storage path, e.g. a GCS URI
But FileRegistryStore uses pathlib.Path which doesn't support GCS URIs.
Meanwhile, Registry.__init__ already has correct scheme-based auto-detection via get_registry_store_class_from_scheme() and REGISTRY_STORE_CLASS_FOR_SCHEME = {"gs": "GCSRegistryStore", ...} — it just never gets a chance because the RegistryConfig is pre-wrapped as "file" type.
Root Cause
In RepoConfig.registry property, the elif isinstance(self.registry_config, str) branch hardcodes:
self._registry = get_registry_config_from_type("file")(path=self.registry_config)
This wraps the path in a file-type config regardless of the URI scheme.
Reproduction
from feast.repo_config import RepoConfig
config = RepoConfig(
project="test",
provider="gcp",
registry="gs://my-bucket/feast/registry.pb",
online_store={"type": "redis", "connection_string": "localhost:6379"},
entity_key_serialization_version=3,
)
# Before fix: config.registry.registry_store_type is implicitly "file"
# -> FileRegistryStore -> Path("gs://...").is_absolute() == False
# -> joins with repo_path -> IsADirectoryError
# After fix: config.registry.registry_store_type is None
# -> Registry.__init__ auto-detects GCSRegistryStore from scheme
Fix
In RepoConfig.registry property, when registry is a string, create a plain RegistryConfig(path=...) instead of hardcoding get_registry_config_from_type("file"). This preserves registry_store_type=None, letting the existing auto-detection in Registry.__init__ select the correct store class based on the URI scheme.
Local file paths continue to work because registry_type defaults to "file" in RegistryConfig, and get_registry_store_class_from_scheme maps the file scheme (and schemeless paths) to FileRegistryStore.
Tests
Added test_registry_string_config.py with 11 tests covering:
- GCS/S3/local string registry → correct
RegistryConfig with registry_store_type=None
- Dict registry (existing behavior preserved)
REGISTRY_STORE_CLASS_FOR_SCHEME maps gs→GCS, s3→S3, file→File
- Unknown schemes raise
pathlib.Path cannot handle cloud URIs (documenting the underlying issue)