Skip to content

FeatureStore.get_online_features() throws FeatureViewNotFoundException #5606

Open

Description

@oonisim

Expected Behavior

Project customer_credit_risk exists in the Feature Store.

for project in feature_store.list_projects():
    print(project)
-----
{
  "spec": {
    "name": "customer_credit_risk",
    "description": "A project for customer credit risk"
  },
  "meta": {
    "createdTimestamp": "2025-09-10T02:36:27.540674Z",
    "lastUpdatedTimestamp": "2025-09-10T07:19:22.520531Z"
  }
}

Feature View customer_credit_risk_feature_view exists.

for fv in feature_store.list_feature_views():
    print(f"FeatureView: {fv.name}")
    for feature in fv.features:
        print(f"  Feature: {feature.name} ({feature.dtype})")
-----
FeatureView: customer_credit_risk_feature_view
  Feature: purpose_business (Float32)
  Feature: purpose_car (Float32)
  Feature: purpose_domestic_appliances (Float32)
...

Materialisation is done.

timestamp = training_df['event_timestamp'][0].to_pydatetime()
feature_store.materialize(
    start_date=datetime.strptime("2025-09-10T00:00:00", "%Y-%m-%dT%H:%M:%S"),
    end_date=datetime.now()
)
---
Materializing 1 feature views from 2025-09-10 00:00:00+00:00 to 2025-09-10 17:29:35+00:00 into the sqlite online store.

Run feature_store.get_online_features().

feature_vector = feature_store.get_online_features(
    features=[
        'customer_credit_risk_customer_credit_risk_feature_view:purpose_business'
    ],
    #features=customer_credit_risk_features,
    entity_rows=[{
            "entity_id": 0,
    }]
).to_df()

Expected to see the data.

Current Behavior

FeatureViewNotFoundException: Feature view customer_credit_risk_customer_credit_risk_feature_view does not exist in project customer_credit_risk

---------------------------------------------------------------------------
FeatureViewNotFoundException              Traceback (most recent call last)
Cell In[80], line 1
----> 1 feature_vector = feature_store.get_online_features(
      2     features=[
      3         'customer_credit_risk_customer_credit_risk_feature_view:purpose_business'
      4     ],
      5     #features=customer_credit_risk_features,
      6     entity_rows=[
      7         {
      8             "entity_id": 0,
      9         }
     10     ]
     11 ).to_df()

File ~/venv/feast/lib/python3.11/site-packages/feast/feature_store.py:2080, in FeatureStore.get_online_features(self, features, entity_rows, full_feature_names)
   2037 """
   2038 Retrieves the latest online feature data.
   2039 
   (...)   2076     >>> online_response_dict = online_response.to_dict()
   2077 """
   2078 provider = self._get_provider()
-> 2080 return provider.get_online_features(
   2081     config=self.config,
   2082     features=features,
   2083     entity_rows=entity_rows,
   2084     registry=self._registry,
   2085     project=self.project,
   2086     full_feature_names=full_feature_names,
   2087 )

File ~/venv/feast/lib/python3.11/site-packages/feast/infra/passthrough_provider.py:251, in PassthroughProvider.get_online_features(self, config, features, entity_rows, registry, project, full_feature_names)
    239 def get_online_features(
    240     self,
    241     config: RepoConfig,
   (...)    249     full_feature_names: bool = False,
    250 ) -> OnlineResponse:
--> 251     return self.online_store.get_online_features(
    252         config=config,
    253         features=features,
    254         entity_rows=entity_rows,
    255         registry=registry,
    256         project=project,
    257         full_feature_names=full_feature_names,
    258     )

File ~/venv/feast/lib/python3.11/site-packages/feast/infra/online_stores/online_store.py:179, in OnlineStore.get_online_features(self, config, features, entity_rows, registry, project, full_feature_names)
    165                 raise ValueError(
    166                     "All entity_rows must have the same keys."
    167                 ) from e
    169     entity_rows = columnar
    171 (
    172     join_key_values,
    173     grouped_refs,
    174     entity_name_to_join_key_map,
    175     requested_on_demand_feature_views,
    176     feature_refs,
    177     requested_result_row_names,
    178     online_features_response,
--> 179 ) = utils._prepare_entities_to_read_from_online_store(
    180     registry=registry,
    181     project=project,
    182     features=features,
    183     entity_values=entity_rows,
    184     full_feature_names=full_feature_names,
    185     native_entity_values=True,
    186 )
    188 for table, requested_features in grouped_refs:
    189     # Get the correct set of entity values with the correct join keys.
    190     table_entity_values, idxs, output_len = utils._get_unique_entities(
    191         table,
    192         join_key_values,
    193         entity_name_to_join_key_map,
    194     )

File ~/venv/feast/lib/python3.11/site-packages/feast/utils.py:1204, in _prepare_entities_to_read_from_online_store(registry, project, features, entity_values, full_feature_names, native_entity_values)
   1182 def _prepare_entities_to_read_from_online_store(
   1183     registry,
   1184     project,
   (...)   1190     native_entity_values: bool = True,
   1191 ):
   1192     from feast.feature_view import DUMMY_ENTITY, DUMMY_ENTITY_ID, DUMMY_ENTITY_VAL
   1194     (
   1195         feature_refs,
   1196         requested_on_demand_feature_views,
   1197         entity_name_to_join_key_map,
   1198         entity_type_map,
   1199         join_keys_set,
   1200         grouped_refs,
   1201         requested_result_row_names,
   1202         needed_request_data,
   1203         entityless_case,
-> 1204     ) = _get_online_request_context(registry, project, features, full_feature_names)
   1206     # Extract Sequence from RepeatedValue Protobuf.
   1207     entity_value_lists: Dict[str, Union[List[Any], List[ValueProto]]] = {
   1208         k: list(v) if isinstance(v, Sequence) else list(v.val)
   1209         for k, v in entity_values.items()
   1210     }

File ~/venv/feast/lib/python3.11/site-packages/feast/utils.py:1127, in _get_online_request_context(registry, project, features, full_feature_names)
   1120 from feast.feature_view import DUMMY_ENTITY_NAME
   1122 _feature_refs = _get_features(registry, project, features, allow_cache=True)
   1124 (
   1125     requested_feature_views,
   1126     requested_on_demand_feature_views,
-> 1127 ) = _get_feature_views_to_use(
   1128     registry=registry,
   1129     project=project,
   1130     features=features,
   1131     allow_cache=True,
   1132     hide_dummy_entity=False,
   1133 )
   1135 (
   1136     entity_name_to_join_key_map,
   1137     entity_type_map,
   1138     join_keys_set,
   1139 ) = _get_entity_maps(registry, project, requested_feature_views)
   1141 _validate_feature_refs(_feature_refs, full_feature_names)

File ~/venv/feast/lib/python3.11/site-packages/feast/utils.py:1075, in _get_feature_views_to_use(registry, project, features, allow_cache, hide_dummy_entity)
   1073 fvs_to_use, od_fvs_to_use = [], []
   1074 for name, projection in feature_views:
-> 1075     fv = registry.get_any_feature_view(name, project, allow_cache)
   1077     if isinstance(fv, OnDemandFeatureView):
   1078         od_fvs_to_use.append(
   1079             fv.with_projection(copy.copy(projection)) if projection else fv
   1080         )

File ~/venv/feast/lib/python3.11/site-packages/feast/infra/registry/caching_registry.py:117, in CachingRegistry.get_any_feature_view(self, name, project, allow_cache)
    115 if allow_cache:
    116     self._refresh_cached_registry_if_necessary()
--> 117     return proto_registry_utils.get_any_feature_view(
    118         self.cached_registry_proto, name, project
    119     )
    120 return self._get_any_feature_view(name, project)

File ~/venv/feast/lib/python3.11/site-packages/feast/infra/registry/proto_registry_utils.py:92, in registry_proto_cache_name.<locals>.wrapper(registry_proto, name, project)
     90     return cache[key]
     91 else:
---> 92     value = func(registry_proto, name, project)
     93     cache[key] = value
     94     return value

File ~/venv/feast/lib/python3.11/site-packages/feast/infra/registry/proto_registry_utils.py:147, in get_any_feature_view(registry_proto, name, project)
    141     if (
    142         on_demand_feature_view.spec.project == project
    143         and on_demand_feature_view.spec.name == name
    144     ):
    145         return OnDemandFeatureView.from_proto(on_demand_feature_view)
--> 147 raise FeatureViewNotFoundException(name, project)

FeatureViewNotFoundException: Feature view customer_credit_risk_customer_credit_risk_feature_view does not exist in project customer_credit_risk

Steps to reproduce

feature_store.yaml* is used just as the configuration file. Not using feast apply command line.

project: customer_credit_risk
registry:
    registry_type: sql
    path: postgresql+psycopg2://postgres@localhost:5432/feast_registry
    cache_ttl_seconds: 60

provider: local
offline_store:
  type: postgres
  host: localhost
  port: 5432
  database: offline_features
  db_schema: credit
  user: dbadm
  password: ****
online_store:
  type: sqlite
  path: data/online_store.db

entity_key_serialization_version: 3
auth:
  type: no_auth

Feature Store instantiation.

feature_store_config = read_yaml(f"{FEATURE_REPO_DIR}/feature_store.yaml")

repo_config = RepoConfig(
    registry=SqlRegistryConfig(
        path="postgresql+psycopg2://postgres@localhost:5432/feast_registry", 
        registry_type="sql",
        sqlalchemy_config_kwargs={
            "echo": False,
            "pool_pre_ping": True,
        }
    ),
    project="customer_credit_risk",
    provider="local",
    offline_store=PostgreSQLOfflineStoreConfig(**feature_store_config['offline_store']),
    online_store=SqliteOnlineStoreConfig(path=f'{FEATURE_REPO_DIR}/data/online_store.db')
)

"""Feature definition
"""
from datetime import timedelta

from feast import (
    Entity,
    FeatureService,
    FeatureView,
    Field,
    Project,
)
from feast.infra.offline_stores.contrib.postgres_offline_store.postgres_source import (
    PostgreSQLSource,
)

from feast.feature_logging import LoggingConfig
from feast.infra.offline_stores.file_source import FileLoggingDestination
from feast.types import Float32, Int64

from utility import (
    get_yaml_value
)


project = Project(
    name=feature_store_config['project'],
    description="A project for customer credit risk"
)

# https://docs.feast.dev/reference/data-sources/postgres
credit_risk_feature_source = PostgreSQLSource(
    name="customer_credit_risk_feature_source",
    query="SELECT * FROM credit.customer_credit_risk_features",
    timestamp_field="event_timestamp",
    created_timestamp_column="created",
)

customer = Entity(name="customer", join_keys=["entity_id"])

credit_risk_feature_view = FeatureView(
    name="customer_credit_risk_feature_view",
    entities=[customer],
    ttl=timedelta(minutes=1),
    # The list of features defined below act as a schema to both define features
    # for both materialization of features into a store, and are used as references
    # during retrieval for building a training dataset or serving features
    schema=[
        Field(name="purpose_business", dtype=Float32),
        Field(name="purpose_car", dtype=Float32),
        Field(name="purpose_domestic_appliances", dtype=Float32),
        Field(name="purpose_education", dtype=Float32),
        Field(name="purpose_furniture_equipment", dtype=Float32),
        Field(name="purpose_radio_tv", dtype=Float32),
        Field(name="purpose_repairs", dtype=Float32),
        Field(name="purpose_vacation_others", dtype=Float32),
        Field(name="gender_female", dtype=Float32),
        Field(name="gender_male", dtype=Float32),
        Field(name="property_free", dtype=Float32),
        Field(name="property_own", dtype=Float32),
        Field(name="property_rent", dtype=Float32),
        Field(name="savings_little", dtype=Float32),
        Field(name="savings_moderate", dtype=Float32),
        Field(name="savings_no_inf", dtype=Float32),
        Field(name="savings_quite_rich", dtype=Float32),
        Field(name="savings_rich", dtype=Float32),
        Field(name="check_little", dtype=Float32),
        Field(name="check_moderate", dtype=Float32),
        Field(name="check_no_inf", dtype=Float32),
        Field(name="check_rich", dtype=Float32),
        Field(name="generation_student", dtype=Float32),
        Field(name="generation_young", dtype=Float32),
        Field(name="generation_adult", dtype=Float32),
        Field(name="generation_senior", dtype=Float32),
        Field(name="job_0", dtype=Float32),
        Field(name="job_1", dtype=Float32),
        Field(name="job_2", dtype=Float32),
        Field(name="job_3", dtype=Float32),
        Field(name="amount_0", dtype=Float32),
        Field(name="amount_1", dtype=Float32),
        Field(name="amount_2", dtype=Float32),
        Field(name="amount_3", dtype=Float32),
        # Field(name="avg_daily_trips", dtype=Int64, description="Average daily trips"),
    ],
    source=credit_risk_feature_source,             # Link to the raw data storage technology
    online=True,                                    # Tell FEAST to materialise into online store.
)

customer_credit_risk_features = FeatureService(
    name="customer_credit_risk_feature_service",
    description="Features for Customer Credit Dirk Model",
    tags={
        "version": "0.1"
    },
    features=[
        credit_risk_feature_view,
    ],
    logging_config=LoggingConfig(
        destination=FileLoggingDestination(path="data")
    ),
)

feature_store.apply(
    objects=[
        project,
        customer,
        credit_risk_feature_source,
        credit_risk_feature_view,
        customer_credit_risk_features
    ]
)

Specifications

  • Version: Feast 0.53 + PostgreSQL (Docker) 15
  • Platform: MacOS
  • Subsystem: Python 3.11

Possible Solution

Activity

  1. oonisim commented on Sep 10, 2025

    @oonisim
    Author

    Data exists in the online store.

    $ sqlite3 data/online_store.db
    SQLite version 3.43.2 2023-10-10 13:08:14
    Enter ".help" for usage hints.
    
    sqlite> .tables
    customer_credit_risk_customer_credit_risk_feature_view
    sqlite> select count(*) from customer_credit_risk_customer_credit_risk_feature_view;
    34000
    
    sqlite> select * from customer_credit_risk_customer_credit_risk_feature_view limit 1;
    |purpose_business|5||1757471770|1757471770
    
  2. Mrun25 commented on Oct 22, 2026

    @Mrun25

    Reproduced this on current main. The root cause is the feature-view name in the ref: customer_credit_risk_customer_credit_risk_feature_view is the online store TABLE name (tables are named {project}_{feature_view}), while the feature view itself is registered as customer_credit_risk_feature_view, which resolves fine. The exception is technically correct but gives no hint, so it reads like a registry/materialization bug.

    I'll open a small PR that makes FeatureViewNotFoundException suggest the available/closest feature view names in the project when a lookup misses, so this class of mistake is self-correcting.

  3. added a commit that references this issue on Oct 22, 2026
    21f9668
  4. Mrun25 commented on Oct 22, 2026

    @Mrun25

    Opened #7059 for this.

  5. added a commit that references this issue on Oct 22, 2026
    a14110d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions