GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Calling get_historical_features for a feature service with an on_demand_feature_view expects the code locally · Issue #5620 · feast-dev/feast

Calling get_historical_features for a feature service with an on_demand_feature_view expects the code locally #5620

New issue
Copy link
New issue
Copy link
Open
Open
Calling get_historical_features for a feature service with an on_demand_feature_view expects the code locally#5620
Copy link
Labels
kind/bugpriority/p2

Description

@amonkhouse
amonkhouse
opened on Sep 17, 2025
Issue body actions

Expected Behavior

Feature retrieval should not depend on local code. This also causes issues deleting/updating the feature store via the CLI.

Current Behavior

If I register a feature service that uses an on_demand_feature_view and try to get historical features from it I get the following error:

Traceback (most recent call last):
  File "/Users/user/Git/repo/test.py", line 14, in <module>
    features = feature_store.get_historical_features(
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/feature_store.py", line 1171, in get_historical_features
    ) = utils._get_feature_views_to_use(self._registry, self.project, features)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/utils.py", line 1075, in _get_feature_views_to_use
    fv = registry.get_any_feature_view(name, project, allow_cache)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/infra/registry/registry.py", line 641, in get_any_feature_view
    return proto_registry_utils.get_any_feature_view(registry_proto, name, project)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/infra/registry/proto_registry_utils.py", line 92, in wrapper
    value = func(registry_proto, name, project)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/infra/registry/proto_registry_utils.py", line 145, in get_any_feature_view
    return OnDemandFeatureView.from_proto(on_demand_feature_view)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/on_demand_feature_view.py", line 393, in from_proto
    transformation = PandasTransformation.from_proto(
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/feast/transformation/pandas_transformation.py", line 150, in from_proto
    udf=dill.loads(user_defined_function_proto.body),
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/dill/_dill.py", line 311, in loads
    return load(file, ignore, **kwds)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/dill/_dill.py", line 297, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/dill/_dill.py", line 452, in load
    obj = StockUnpickler.load(self)
  File "/Users/user/.pyenv/versions/repo/lib/python3.10/site-packages/dill/_dill.py", line 442, in find_class
    return StockUnpickler.find_class(self, module, name)
ModuleNotFoundError: No module named 'feature_services'

I don't get this error if I'm running it from a location that it can find this module, but of course we want to deploy this feature service to the feature store and call it from elsewhere.

Steps to reproduce

I am using a Redshift Offline Source.

feature service code:

merchandisability_feature_store = FeatureService(
    name="merchandisability",
    features=[
        artwork_inquiries_feature_view,
        artwork_metadata_feature_view,
        artist_metadata_feature_view,
        partner_metadata_feature_view,
        purchase_metadata_feature_view,
        artwork_age, <-- on demand feature view
    ],
)

and I try to get features like so:

df = pd.DataFrame.from_dict(
    {"user_id": ["user1"], "event_timestamp": datetime.now()}
)
feature_service = feature_store.get_feature_service("merchandisability")
features = feature_store.get_historical_features(
    features=feature_service,
    entity_df=df,
)

Specifications

  • Version: 0.53.0
  • Platform: MacOS 15.4.1
  • Subsystem:

Possible Solution

🤷

Reacted by BigyaPradhan

Activity

  1. amonkhouse
    added
    kind/bug
    priority/p2
    on Sep 17, 2025
  2. BigyaPradhan commented on Oct 2, 2025

    @BigyaPradhan
    BigyaPradhan
    on Oct 2, 2025
    More actions

    This also stops feast ui from working.

  3. adarshsm commented on Jul 30, 2026

    @adarshsm
    adarshsm
    on Jul 30, 2026
    Contributor
    More actions

    Root cause: ODFV loading eagerly deserializes the UDF. get_any_feature_view (sdk/python/feast/infra/registry/proto_registry_utils.py:151) calls OnDemandFeatureView.from_proto without skip_udf, which runs _parse_transformation_from_proto → Pandas/PythonTransformation.from_proto → dill.loads(body). So any registry read that resolves an ODFV — list, feast ui, get_historical_features — raises ModuleNotFoundError when a single ODFV's UDF imports a module that isn't present in the reading environment, even for operations that never execute the UDF.

    The skip_udf path already exists (_parse_transformation_from_proto returns None when it's set, and list_all_feature_views threads it through — the write path uses it), but get_any_feature_view and the default read paths don't pass it, so they still crash.

    A few directions, each a slightly different philosophy — wanted to check which you'd prefer before implementing:

    1. Per-FV resilience on read: catch a single ODFV's deserialization failure during registry reads, log a warning, and degrade just that view (keeping body_text/udf_string for display) so one bad UDF doesn't break reads of everything else. Executing that specific ODFV still fails loudly.
    2. Extend skip_udf to the read paths that never execute UDFs (feast ui, list, delete), consistent with the existing opt-in approach.
    3. Lazy deserialization: defer dill.loads until the UDF is actually invoked.

    (1) fixes the reported symptoms with the least surface area and no change to a working view's semantics; (2) stays closest to the current skip_udf design; (3) is the most thorough but the largest change. Happy to implement whichever direction you'd prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugpriority/p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.