Repository navigation
Merge remote-tracking branch 'upstream/master' - #117
Conversation
…Dockerfile COPY permissions Signed-off-by: ntkathole <[email protected]>
Signed-off-by: ntkathole <[email protected]>
Signed-off-by: ntkathole <[email protected]>
Signed-off-by: ntkathole <[email protected]>
* Initial plan * fix: use blog hero image for social preview metadata Agent-Logs-Url: https://github.com/feast-dev/feast/sessions/8c33bcc6-0cd4-4222-95a1-bfa02f136b5b Co-authored-by: franciscojavierarceo <[email protected]> * fix: harden hero image extraction for blog social tags Agent-Logs-Url: https://github.com/feast-dev/feast/sessions/8c33bcc6-0cd4-4222-95a1-bfa02f136b5b Co-authored-by: franciscojavierarceo <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: franciscojavierarceo <[email protected]>
📝 WalkthroughWalkthroughThis PR adds end-to-end support for Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Security & Quality Issues1. Type Inference Risk in Empty dicts still infer as Recommendation: Document this edge case explicitly in feature view schemas where 2. Incomplete Key Type Validation in The function accepts Recommendation: Add explicit range/validity checks for numeric types; reject NaN/Inf for floats; validate UUID string format before encoding. 3. Circular Dependency Risk in Protobuf Stub Regeneration The 40+ regenerated Recommendation: Run import cycle detection on the full protobuf module tree (e.g., 4. Missing Validation for Materialization Constraints Documentation (lines 420–457 in Recommendation: Add a validation error if a feature view with 5. Dockerfile Ownership Fix Incomplete (infra/feast-operator/Dockerfile, lines 8–17) Only Recommendation: Verify that user 1001 owns/has access to all build directories; consider using 6. Go Module Indirect Dependency Drift (infra/feast-operator/go.mod) Indirect dependencies (e.g., Recommendation: Document the reason for each indirect dependency bump; verify that no CVEs were introduced (e.g., cross-check with https://nvd.nist.gov/). |
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
infra/feast-operator/Dockerfile (1)
2-2:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winBuilder image tag
go-toolset:1.24is floating — pin to a specific digest or patch tag.The
1.24tag floats across patch releases of the Go 1.24 toolchain. A silent update to the UBI base can silently change the build environment and compiler behavior. Pin to a specific patch release (e.g.,go-toolset:1.24.4) or use an@sha256:…digest to make builds fully reproducible.As per coding guidelines: "Use specific image tags (not :latest)".
🔒 Proposed fix
-FROM registry.access.redhat.com/ubi9/go-toolset:1.24 AS builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.24.4 AS builder(replace
1.24.4with the specific patch available in the UBI registry)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/feast-operator/Dockerfile` at line 2, The FROM image in the Dockerfile currently uses the floating tag "registry.access.redhat.com/ubi9/go-toolset:1.24"; replace this with a non-floating identifier (either a specific patch tag like "go-toolset:1.24.4" or the image digest "@sha256:...") so builds are reproducible and the build environment cannot change silently; update the FROM line accordingly in the Dockerfile reference to "registry.access.redhat.com/ubi9/go-toolset:1.24" so the new pinned tag or digest is used.infra/feast-operator/go.mod (1)
72-72:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
go.opentelemetry.io/otel/sdk v1.33.0has two unpatched PATH-hijacking CVEs — upgrade to ≥ v1.43.0.
- GHSA-9h8m-3fm2-qjrq (CVE-2026-24051, CVSS 7.0): the SDK executes the
ioregsystem command via a search path on macOS/Darwin; a local attacker who can modify$PATHachieves arbitrary code execution. Fixed inv1.40.0.- GHSA-hfvc-g4fc-pqhx (CVE-2026-39883): the follow-on fix for the above left the BSD
kenvcommand using a bare name, allowing the same attack on BSD/Solaris platforms — affected range>= v1.15.0, <= v1.42.0; fixed inv1.43.0.Both CVEs require only a local attacker. Add an explicit pin at
v1.43.0or higher to cover both.🔒 Proposed minimum fix
- go.opentelemetry.io/otel/sdk v1.33.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect — CVE-2026-24051 + CVE-2026-39883 fix🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/feast-operator/go.mod` at line 72, The go.mod entry for the OpenTelemetry SDK (go.opentelemetry.io/otel/sdk v1.33.0) is vulnerable to PATH-hijacking CVEs; update the module version to at least v1.43.0 by replacing the existing go.opentelemetry.io/otel/sdk v1.33.0 line with an explicit pin to v1.43.0 (or newer) so the project uses the patched SDK and re-run go mod tidy to refresh the dependency graph referenced by go.opentelemetry.io/otel/sdk.
🧹 Nitpick comments (1)
infra/website/src/pages/blog/[slug].astro (1)
6-6: ⚡ Quick winPrefer
Astro.siteover a hardcodedSITE_URL.Astro exposes
Astro.url(current page URL) and the configured base viaAstro.site. Hardcoding'https://feast.dev'in two places (SITE_URLconstant and theogUrldefault inBaseLayout) creates silent drift if the domain ever changes and bypasses the canonical source of truth inastro.config.mjs.🛠️ Proposed refactor
In
astro.config.mjs(if not already set):export default defineConfig({ site: 'https://feast.dev', // ... });Then in
[slug].astro:-const SITE_URL = 'https://feast.dev'; - -function toAbsoluteUrl(path: string): string { - if (/^https?:\/\//i.test(path)) { - return path; - } - return new URL(path, SITE_URL).toString(); -} +function toAbsoluteUrl(path: string, base: URL | string): string { + if (/^https?:\/\//i.test(path)) { + return path; + } + return new URL(path, base).toString(); +} -const blogUrl = `${SITE_URL}/blog/${Astro.params.slug}/`; +const blogUrl = new URL(`/blog/${Astro.params.slug}/`, Astro.site).toString(); // ... -const socialImage = heroImage ? toAbsoluteUrl(heroImage) : undefined; +const socialImage = heroImage ? toAbsoluteUrl(heroImage, Astro.site ?? 'https://feast.dev') : undefined;Also applies to: 39-39
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/website/src/pages/blog/`[slug].astro at line 6, The SITE_URL constant is hardcoded; replace its usage with Astro.site (the canonical site from astro.config.mjs) so the page and the BaseLayout default ogUrl derive from Astro.site instead of a literal 'https://feast.dev'. Remove or stop exporting the const SITE_URL and update references in this file and the BaseLayout invocation (ogUrl default) to use Astro.site (or construct URLs with new URL(Astro.url.pathname, Astro.site) where needed) ensuring no other hardcoded domain strings remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/publish_images.yml:
- Around line 41-43: Replace mutable action tags with pinned commit SHAs: for
each "uses: actions/checkout@v4" (and the other "uses: actions/..." occurrences
referenced in the review) update the value to the corresponding full commit SHA
from the actions' GitHub repo (e.g., fetch the latest commit SHA for the v4 tag
of actions/checkout) so the workflow uses "uses:
actions/checkout@<full-commit-sha>". Do this for every external action
occurrence flagged (the checkout and the other actions at the referenced
locations) to ensure all external actions are pinned to immutable SHAs.
In `@docs/getting-started/concepts/feast-types.md`:
- Line 15: The sentence about Map vs ScalarMap conflates two different inference
contexts; update the text to explicitly separate Python-level type inference
(function python_type_to_feast_value_type infers ScalarMap when the first dict
key is non-string) from backend/storage/schema behavior (backends do not infer
SCALAR_MAP from stored data and therefore ScalarMap must be explicitly declared
in the Feast schema). Refer to the types Map and ScalarMap and the
python_type_to_feast_value_type inference point, and reword the paragraph so it
first describes Map/ScalarMap shapes and Python inference, then a separate
sentence stating the requirement that ScalarMap must be declared in the schema
because backends do not perform this inference.
In `@go/infra/docker/feature-server/Dockerfile`:
- Line 1: The Dockerfile currently uses a floating base image tag in the FROM
instruction ("FROM golang:1.25"); update that line to pin the base image to a
specific patch version and its immutable digest (e.g., replace the floating tag
with a concrete patch tag plus `@sha256`:<digest>) so the build is reproducible
and provenance is preserved; locate the FROM golang:1.25 line in the Dockerfile
and replace it with the chosen patch+digest reference, then rebuild to verify
the digest matches the expected image.
- Line 2: Change the Dockerfile environment setting so release images use a
local, deterministic Go toolchain: replace the GOTOOLCHAIN value currently set
to "auto" with "local" for the release image build to prevent on-demand
downloads; update the ENV declaration for GOTOOLCHAIN in the Dockerfile (the
existing ENV GOTOOLCHAIN=auto) so release builds do not perform network
toolchain fetches and produce reproducible artifacts.
In `@infra/feast-operator/go.mod`:
- Line 89: The go.mod currently lists an indirect vulnerable dependency
"google.golang.org/grpc v1.68.1"; update go.mod to ensure grpc is at least
v1.79.3 by either adding an explicit require for "google.golang.org/grpc
v1.79.3" or using a replace/override to pin that module, or by bumping the
direct modules that pull it in (e.g., "sigs.k8s.io/controller-runtime" and
"github.com/prometheus-operator/prometheus-operator/pkg/client") to versions
that depend on grpc v1.79.3+; run "go mod tidy" after the change to update the
go.sum and vendor files.
In `@infra/website/docs/blog/mongodb-feast-integration.md`:
- Around line 67-73: Replace inline credential examples in the connection_string
fields with environment-variable based placeholders and guidance: change the
shown values for connection_string (both top-level connection_string and
offline_store.connection_string) to reference env vars (e.g., MONGODB_URI or
separate MONGODB_USER/MONGODB_PASSWORD) and add a short note that credentials
must be injected from the environment and that usernames/passwords must be
URL-encoded; update the documentation blocks near the connection_string and
offline_store entries to remove patterns like
mongodb+srv://<user>:<password>@... and instead show a safe example that
references env vars and explains URL-encoding requirements.
- Around line 44-45: The docs use two formats for distance metrics (lowercase
strings like `cosine`, `dot product`, `euclidean` in the
`vector_enabled`/`vector_index=True` explanation and uppercase enum-like values
like `COSINE` in the examples for `retrieve_online_documents_v2()`), causing
copy/paste errors; pick one canonical format (recommend lowercase string
literals: "cosine", "dot_product", "euclidean") and update all
occurrences—including the explanatory paragraph and the examples referenced
around `retrieve_online_documents_v2()` and any snippets at lines ~164 and
~187—so every snippet and description uses the same metric names consistently.
In `@infra/website/src/layouts/BaseLayout.astro`:
- Around line 38-41: The current fixed meta tags og:image:width (1201),
og:image:height (630) and og:image:type ("image/png") are incorrect for per-post
socialImage; update BaseLayout.astro to accept optional props ogImageWidth,
ogImageHeight, ogImageType (defaults matching the fallback [email protected]) and
use those props for the meta tags for og:image:width, og:image:height and
og:image:type (or, alternatively, omit those meta tags when socialImage !==
fallbackImage); ensure you reference the socialImage prop and replace the
hardcoded values in the meta tag nodes so callers can pass true dimensions and
MIME type for per-post images.
In `@infra/website/src/pages/blog/`[slug].astro:
- Around line 15-22: The extractHeroImage function's outer regex uses a
non-greedy capture up to the first </div>, which misses an <img> that appears
after a nested sibling closing tag; change the logic to first locate the opening
<div> with class "hero-image" (match the opening tag only, e.g. via
/<div[^>]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>/i) then take the
substring starting after that opening-tag match and search forward for the first
<img ... src="..."> (e.g. use a second regex
/<img[^>]*\bsrc=["']([^"']+)["'][^>]*>/i on that substring) and return its src
if found; update extractHeroImage to implement this two-step search so
nested/sibling tags no longer cause the img to be missed.
In `@sdk/python/feast/type_map.py`:
- Around line 258-265: When decoding ScalarMap in _handle_scalar_map_value,
detect Python-key collisions produced by _map_key_to_python_value (e.g., True ==
1) instead of silently overwriting: before assigning result[key] = value, check
if key is already present in result and if so raise a clear exception (e.g.,
ValueError) that includes both the conflicting proto entry information and the
existing key/value to prevent silent data loss; update any callers/tests
accordingly to expect this failure mode.
- Line 1426: Add explicit handling for SCALAR_MAP in both conversion helpers:
update feast_value_type_to_pandas_type to include a branch mapping
ValueType.SCALAR_MAP to an appropriate pandas dtype (e.g., pandas.ObjectDtype or
pandas dtype 'object') instead of falling back, and update
_convert_value_type_str_to_value_type to recognize the string key used in the
proto mapping ("scalar_map_val") and return ValueType.SCALAR_MAP. Modify the
code inside the functions feast_value_type_to_pandas_type and
_convert_value_type_str_to_value_type to include these new cases so SCALAR_MAP
no longer hits the TypeError/STRING fallback.
In `@sdk/python/feast/types.py`:
- Line 135: The SCALAR_MAP Feast type is not mapped to PyArrow causing
KeyError/ValueError; add ValueType.SCALAR_MAP: pyarrow.binary() to the type_map
dict used by feast_value_type_to_pa (type_map.py) and add ScalarMap:
pyarrow.binary() to FEAST_TYPES_TO_PYARROW_TYPES in types.py (ScalarMap is
defined as PrimitiveFeastType.SCALAR_MAP), then add a unit test named
test_feast_value_type_to_pa_scalar_map that calls
feast_value_type_to_pa(ValueType.SCALAR_MAP) and asserts the result equals
pyarrow.binary().
In `@sdk/python/tests/unit/test_type_map.py`:
- Around line 2026-2032: In test_empty_value_map, ensure the encoded proto
actually set the scalar_map field and the decoded result is empty: after calling
python_values_to_proto_values([{}], ValueType.SCALAR_MAP) assert that
protos[0].WhichOneof('val') == 'scalar_map_val' (or that
protos[0].scalar_map_val is not an empty/default ProtoValue) and then assert
that feast_value_type_to_python_type(protos[0]) == {} to verify the decoded dict
is empty; keep the existing isinstance check if desired but add these two
explicit assertions to validate both encoding and decoding.
---
Outside diff comments:
In `@infra/feast-operator/Dockerfile`:
- Line 2: The FROM image in the Dockerfile currently uses the floating tag
"registry.access.redhat.com/ubi9/go-toolset:1.24"; replace this with a
non-floating identifier (either a specific patch tag like "go-toolset:1.24.4" or
the image digest "@sha256:...") so builds are reproducible and the build
environment cannot change silently; update the FROM line accordingly in the
Dockerfile reference to "registry.access.redhat.com/ubi9/go-toolset:1.24" so the
new pinned tag or digest is used.
In `@infra/feast-operator/go.mod`:
- Line 72: The go.mod entry for the OpenTelemetry SDK
(go.opentelemetry.io/otel/sdk v1.33.0) is vulnerable to PATH-hijacking CVEs;
update the module version to at least v1.43.0 by replacing the existing
go.opentelemetry.io/otel/sdk v1.33.0 line with an explicit pin to v1.43.0 (or
newer) so the project uses the patched SDK and re-run go mod tidy to refresh the
dependency graph referenced by go.opentelemetry.io/otel/sdk.
---
Nitpick comments:
In `@infra/website/src/pages/blog/`[slug].astro:
- Line 6: The SITE_URL constant is hardcoded; replace its usage with Astro.site
(the canonical site from astro.config.mjs) so the page and the BaseLayout
default ogUrl derive from Astro.site instead of a literal 'https://feast.dev'.
Remove or stop exporting the const SITE_URL and update references in this file
and the BaseLayout invocation (ogUrl default) to use Astro.site (or construct
URLs with new URL(Astro.url.pathname, Astro.site) where needed) ensuring no
other hardcoded domain strings remain.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 7c7c6b0e-f02f-4c34-b440-f666323b021e
⛔ Files ignored due to path filters (2)
infra/feast-operator/go.sumis excluded by!**/*.sum,!**/*.suminfra/website/public/images/blog/mongodb-feature-stores.pngis excluded by!**/*.png
📒 Files selected for processing (49)
.github/workflows/publish_images.ymldocs/getting-started/concepts/feast-types.mddocs/reference/type-system.mdgo/infra/docker/feature-server/Dockerfileinfra/feast-operator/Dockerfileinfra/feast-operator/Makefileinfra/feast-operator/go.modinfra/website/docs/blog/mongodb-feast-integration.mdinfra/website/src/layouts/BaseLayout.astroinfra/website/src/pages/blog/[slug].astroprotos/feast/types/Value.protopyproject.tomlsdk/python/feast/protos/feast/core/Aggregation_pb2.pyisdk/python/feast/protos/feast/core/DataFormat_pb2.pyisdk/python/feast/protos/feast/core/DataSource_pb2.pyisdk/python/feast/protos/feast/core/DatastoreTable_pb2.pyisdk/python/feast/protos/feast/core/Entity_pb2.pyisdk/python/feast/protos/feast/core/FeatureService_pb2.pyisdk/python/feast/protos/feast/core/FeatureTable_pb2.pyisdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.pyisdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.pyisdk/python/feast/protos/feast/core/FeatureView_pb2.pyisdk/python/feast/protos/feast/core/Feature_pb2.pyisdk/python/feast/protos/feast/core/InfraObject_pb2.pyisdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyisdk/python/feast/protos/feast/core/Permission_pb2.pyisdk/python/feast/protos/feast/core/Policy_pb2.pyisdk/python/feast/protos/feast/core/Project_pb2.pyisdk/python/feast/protos/feast/core/Registry_pb2.pyisdk/python/feast/protos/feast/core/SavedDataset_pb2.pyisdk/python/feast/protos/feast/core/SqliteTable_pb2.pyisdk/python/feast/protos/feast/core/Store_pb2.pyisdk/python/feast/protos/feast/core/StreamFeatureView_pb2.pyisdk/python/feast/protos/feast/core/Transformation_pb2.pyisdk/python/feast/protos/feast/core/ValidationProfile_pb2.pyisdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyisdk/python/feast/protos/feast/serving/Connector_pb2.pyisdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyisdk/python/feast/protos/feast/serving/ServingService_pb2.pyisdk/python/feast/protos/feast/serving/TransformationService_pb2.pyisdk/python/feast/protos/feast/storage/Redis_pb2.pyisdk/python/feast/protos/feast/types/EntityKey_pb2.pyisdk/python/feast/protos/feast/types/Field_pb2.pyisdk/python/feast/protos/feast/types/Value_pb2.pysdk/python/feast/protos/feast/types/Value_pb2.pyisdk/python/feast/type_map.pysdk/python/feast/types.pysdk/python/feast/value_type.pysdk/python/tests/unit/test_type_map.py
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.inputs.ref || github.ref }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/publish_images.yml | sed -n '35,50p'Repository: opendatahub-io/feast
Length of output: 814
🏁 Script executed:
rg 'uses:.*actions/' .github/workflows/publish_images.ymlRepository: opendatahub-io/feast
Length of output: 261
🏁 Script executed:
rg -n 'uses:' .github/workflows/publish_images.ymlRepository: opendatahub-io/feast
Length of output: 408
Pin actions/checkout by full commit SHA.
actions/checkout@v4 uses a mutable tag, creating a supply-chain attack surface (CWE-494). All external actions in this workflow must be pinned to a full commit SHA. This applies to lines 41, 51, 53, 57, 63, and 67.
Suggested fix for line 41
- - uses: actions/checkout@v4
+ - uses: actions/checkout@e2f74ab2b41a8e7e710e34cb792faad430156491
with:
ref: ${{ github.event.inputs.ref || github.ref }}
submodules: 'true'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.inputs.ref || github.ref }} | |
| - uses: actions/checkout@e2f74ab2b41a8e7e710e34cb792faad430156491 | |
| with: | |
| ref: ${{ github.event.inputs.ref || github.ref }} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish_images.yml around lines 41 - 43, Replace mutable
action tags with pinned commit SHAs: for each "uses: actions/checkout@v4" (and
the other "uses: actions/..." occurrences referenced in the review) update the
value to the corresponding full commit SHA from the actions' GitHub repo (e.g.,
fetch the latest commit SHA for the v4 tag of actions/checkout) so the workflow
uses "uses: actions/checkout@<full-commit-sha>". Do this for every external
action occurrence flagged (the checkout and the other actions at the referenced
locations) to ensure all external actions are pinned to immutable SHAs.
| - **Array types**: ordered lists of any primitive type, e.g. `Array(Int64)`, `Array(String)`, `Array(Uuid)`. | ||
| - **Set types**: unordered collections of unique values for any primitive type, e.g. `Set(String)`, `Set(Int64)`. Set types are not inferred by any backend and must be explicitly declared. They are best suited for online serving use cases. | ||
| - **Map types**: dictionary-like structures with string keys and values that can be any supported Feast type (including nested maps), e.g. `Map`, `Array(Map)`. | ||
| - **Map types**: dictionary-like structures. `Map` has string keys and values that can be any supported Feast type (including nested maps), e.g. `Map`, `Array(Map)`. `ScalarMap` has non-string scalar keys (int, float, bool, UUID, Decimal, bytes, datetime) — Feast infers `ScalarMap` automatically when the first key is not a string. `ScalarMap` must be explicitly declared in schema and is not inferred by any backend. |
There was a problem hiding this comment.
Clarify the two distinct inference contexts to resolve apparent contradiction.
The sentence states both that ScalarMap is auto-inferred and that it must be explicitly declared in schema, which reads as contradictory. The first refers to Python-level dict type inference (python_type_to_feast_value_type); the second means no backend reads stored data and infers the Feast type as SCALAR_MAP. These need to be separated:
-- **Map types**: dictionary-like structures. `Map` has string keys and values that can be any supported Feast type (including nested maps), e.g. `Map`, `Array(Map)`. `ScalarMap` has non-string scalar keys (int, float, bool, UUID, Decimal, bytes, datetime) — Feast infers `ScalarMap` automatically when the first key is not a string. `ScalarMap` must be explicitly declared in schema and is not inferred by any backend.
+- **Map types**: dictionary-like structures. `Map` has string keys and values that can be any supported Feast type (including nested maps), e.g. `Map`, `Array(Map)`. `ScalarMap` has non-string scalar keys (int, float, bool, UUID, Decimal, bytes, datetime). When Feast SDK inspects a Python dict and the first key is not a string, it infers `ValueType.SCALAR_MAP`; an empty dict (`{}`) defaults to `Map`. `ScalarMap` **must be explicitly declared in the feature view schema** — no backend reads stored bytes and auto-detects the type as `ScalarMap`.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/getting-started/concepts/feast-types.md` at line 15, The sentence about
Map vs ScalarMap conflates two different inference contexts; update the text to
explicitly separate Python-level type inference (function
python_type_to_feast_value_type infers ScalarMap when the first dict key is
non-string) from backend/storage/schema behavior (backends do not infer
SCALAR_MAP from stored data and therefore ScalarMap must be explicitly declared
in the Feast schema). Refer to the types Map and ScalarMap and the
python_type_to_feast_value_type inference point, and reword the paragraph so it
first describes Map/ScalarMap shapes and Python inference, then a separate
sentence stating the requirement that ScalarMap must be declared in the schema
because backends do not perform this inference.
| @@ -1,4 +1,5 @@ | |||
| FROM golang:1.24.12 | |||
| FROM golang:1.25 | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat go/infra/docker/feature-server/DockerfileRepository: opendatahub-io/feast
Length of output: 1057
Pin the base image to an immutable digest.
Line 1 uses a floating tag (golang:1.25), which can silently change build contents on rebuild and weaken provenance controls (CWE-494). Pin to a specific patch tag with digest.
Suggested fix
-FROM golang:1.25
+FROM golang:1.25.0@sha256:<verified-manifest-digest>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@go/infra/docker/feature-server/Dockerfile` at line 1, The Dockerfile
currently uses a floating base image tag in the FROM instruction ("FROM
golang:1.25"); update that line to pin the base image to a specific patch
version and its immutable digest (e.g., replace the floating tag with a concrete
patch tag plus `@sha256`:<digest>) so the build is reproducible and provenance is
preserved; locate the FROM golang:1.25 line in the Dockerfile and replace it
with the chosen patch+digest reference, then rebuild to verify the digest
matches the expected image.
| @@ -1,4 +1,5 @@ | |||
| FROM golang:1.24.12 | |||
| FROM golang:1.25 | |||
| ENV GOTOOLCHAIN=auto | |||
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Go GOTOOLCHAIN environment variable auto local security
💡 Result:
The GOTOOLCHAIN environment variable controls Go toolchain selection, with the default value 'auto' (shorthand for 'local+auto') enabling automatic switching to newer toolchains when required by go.mod or go.work files [1][2]. In 'auto' mode, if a newer toolchain is needed, the go command downloads it from go.dev/dl as a special module under golang.org/toolchain, specific to the GOOS/GOARCH [1][2][3]. Security is ensured through verification against the public Go checksum database (sum.golang.org), a transparency log containing checksums for all toolchains [2][3][4]. Downloads fail if GOSUMDB=off, and GOPRIVATE/GONOSUMDB do not bypass this check [2]. Independent auditors like Source Spotter verify reproducibility by rebuilding toolchains from source and confirming checksum matches, providing assurance against tampering [3][4][5]. Toolchains are reproducible bit-for-bit (with minor exceptions like signatures), verifiable via gorebuild [6][7]. To disable auto-downloads for security or control, set GOTOOLCHAIN=local (uses bundled toolchain only) or a specific version [1][2][8]. No active security risks with 'auto' in current Go versions (as of 2026-05-08), though past CVEs like CVE-2025-68119 addressed unrelated invocation issues [9].
Citations:
- 1: https://golang-org.appspot.com/go.dev/doc/toolchain
- 2: https://go.dev/doc/toolchain
- 3: https://www.adityathebe.com/go-toolchain-download/
- 4: https://www.agwa.name/blog/post/verifying_go_reproducible_builds
- 5: https://sourcespotter.com/toolchain/
- 6: https://golang.org/blog/rebuild
- 7: https://go.dev/rebuild
- 8: https://news.ycombinator.com/item?id=41298116
- 9: https://go.dev/issue/77099
🌐 Web query:
GOTOOLCHAIN=auto downloads remote toolchain Go
💡 Result:
Yes, when GOTOOLCHAIN=auto (the default setting), the Go command downloads a remote toolchain automatically if needed. This occurs when the current bundled toolchain is too old for the go.mod or go.work file's requirements (e.g., a 'go 1.22.0' directive with Go 1.21 installed), or a specific 'toolchain' directive specifies a newer version [1][2]. The download happens from golang.org/toolchain as a special module (e.g., v0.0.1-go1.22.0-linux-amd64), respecting GOPROXY and GOSUMDB, and the toolchain is installed alongside the existing one in $GOPATH/pkg/mod, not replacing it [1][2]. Examples include 'go mod download', 'go build', or even 'go version' in a module requiring a newer Go [3][4]. To disable, set GOTOOLCHAIN=local [2]. This feature started in Go 1.21 and remains current as of Go 1.25+ docs [5][2].
Citations:
- 1: https://golang-org.appspot.com/go.dev/doc/toolchain
- 2: https://go.dev/doc/toolchain
- 3: https://go.dev/issue/66562
- 4: cmd/go: automatic toolchain upgrades make the combination of
go versionandgo install <package>@<version>confusing golang/go#66518 - 5: https://go.dev/cmd/go/internal/toolchain%40go1.25.1
🌐 Web query:
Go toolchain remote download GOTOOLCHAIN=auto CWE-494
💡 Result:
GOTOOLCHAIN=auto remote download: what it is and how it maps to CWE-494 1) What GOTOOLCHAIN=auto does (Go behavior) - The go command consults GOTOOLCHAIN at startup to decide which Go toolchain to run; GOTOOLCHAIN=auto is shorthand for GOTOOLCHAIN=local+auto, meaning it prefers the bundled/local toolchain but will download a newer one “as needed” [1]. - When it needs to download, the toolchains are packaged as special modules with path golang.org/toolchain and versions like v0.0.1-goVERSION.GOOS-GOARCH. Toolchain downloads are done like other module downloads: they can use GOPROXY and have checksums checked via the checksum database, and failures can occur when verification can’t be performed (for example, if toolchain downloads can’t be verified with GOSUMDB=off) [1]. 2) “Remote download GOTOOLCHAIN=auto” (does it actually download?) - Yes: with GOTOOLCHAIN=auto (local+auto), if the workspace/module requests a newer Go version (via the go or toolchain directives), and that toolchain isn’t already available, go will download and run it [1]. 3) Is this “CWE-494 Download of Code Without Integrity Check”? - CWE-494’s core definition is downloading code/executables remotely and executing them without sufficiently verifying origin/integrity [2]. - In Go’s toolchain auto-download design, the toolchain artifacts are intended to be integrity-checked like normal modules (checksum database verification and signature checks for module sums). The Go toolchain documentation explicitly says toolchain downloads have checksums checked by the Go checksum database, and that downloads can fail if they can’t be verified (e.g., lack of verification if GOSUMDB=off) [1]. - Therefore, “GOTOOLCHAIN=auto” itself is not described by Go’s official documentation as “download without integrity check”; instead, it is described as a mechanism that performs verification comparable to the module system [1]. 4) Security caveat: integrity/verification can still be bypassed or become unsafe in specific threat models - Even with the intended checksum/integrity model, real-world risk can still emerge if the environment undermines verification or if there are toolchain-related vulnerabilities. For example, Go has had security issues in cmd/go/toolchain behavior (CVE reports exist for cmd/go and toolchain), which means the overall “safe execution” story depends on using a supported, patched Go version and a secure module/toolchain download environment [3]. Practical guidance to reduce CWE-494-like risk - Keep GOSUMDB enabled (don’t disable checksum database verification); Go notes that toolchain downloads fail for lack of verification if GOSUMDB=off [1]. - In high-security/air-gapped CI, consider disabling automatic downloads by setting GOTOOLCHAIN=local (documented by community CI usage and consistent with the toolchain selection semantics) [1]. If you want, tell me your Go version and whether you’re using go directive only (go X) or a toolchain directive (toolchain goX.Y.Z) in go.mod/go.work, and I can explain exactly when go will trigger the remote toolchain download under GOTOOLCHAIN=auto, based on the official selection rules [1].
Citations:
- 1: https://go.dev/doc/toolchain
- 2: https://cwe.mitre.org/data/definitions/494
- 3: https://go.dev/issue/77099
Use GOTOOLCHAIN=local in release image builds for deterministic builds.
Line 2 with GOTOOLCHAIN=auto allows the Go command to download newer toolchains from golang.org/toolchain when needed, making builds non-deterministic and introducing a network dependency. While Go's toolchain downloads are integrity-checked via the public checksum database (sum.golang.org), disabling auto-downloads in release builds ensures consistent, reproducible artifacts without external dependencies.
Suggested fix
-ENV GOTOOLCHAIN=auto
+ENV GOTOOLCHAIN=local📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ENV GOTOOLCHAIN=auto | |
| ENV GOTOOLCHAIN=local |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@go/infra/docker/feature-server/Dockerfile` at line 2, Change the Dockerfile
environment setting so release images use a local, deterministic Go toolchain:
replace the GOTOOLCHAIN value currently set to "auto" with "local" for the
release image build to prevent on-demand downloads; update the ENV declaration
for GOTOOLCHAIN in the Dockerfile (the existing ENV GOTOOLCHAIN=auto) so release
builds do not perform network toolchain fetches and produce reproducible
artifacts.
| gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect | ||
| google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect | ||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect | ||
| google.golang.org/grpc v1.68.1 // indirect |
There was a problem hiding this comment.
Critical: google.golang.org/grpc v1.68.1 carries CVE-2026-33186 (GHSA-p77j-4mvh-x3m3), CVSS 9.1.
The gRPC-Go server accepts requests where the HTTP/2 :path pseudo-header omits the mandatory leading slash, and authorization interceptors evaluate the raw, non-canonical path — causing deny rules to fail to match. All versions of google.golang.org/grpc before v1.79.3 are affected; the fix is v1.79.3.
This is an indirect dependency. Bump the direct deps that pull it in (e.g., sigs.k8s.io/controller-runtime, github.com/prometheus-operator/prometheus-operator/pkg/client) or add an explicit override:
🔒 Proposed minimum fix (explicit indirect pin)
require (
github.com/prometheus-operator/prometheus-operator/pkg/client v0.83.0
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979
+ google.golang.org/grpc v1.79.3 // indirect — CVE-2026-33186 fix
)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@infra/feast-operator/go.mod` at line 89, The go.mod currently lists an
indirect vulnerable dependency "google.golang.org/grpc v1.68.1"; update go.mod
to ensure grpc is at least v1.79.3 by either adding an explicit require for
"google.golang.org/grpc v1.79.3" or using a replace/override to pin that module,
or by bumping the direct modules that pull it in (e.g.,
"sigs.k8s.io/controller-runtime" and
"github.com/prometheus-operator/prometheus-operator/pkg/client") to versions
that depend on grpc v1.79.3+; run "go mod tidy" after the change to update the
go.sum and vendor files.
| function extractHeroImage(markdown: string): string | undefined { | ||
| const heroContainerMatch = markdown.match(/<div[^>]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>([\s\S]*?)<\/div>/i); | ||
| if (!heroContainerMatch?.[1]) { | ||
| return undefined; | ||
| } | ||
| const imageMatch = heroContainerMatch[1].match(/<img[^>]*\bsrc=["']([^"']+)["'][^>]*>/i); | ||
| return imageMatch?.[1]; | ||
| } |
There was a problem hiding this comment.
extractHeroImage regex silently drops the hero image when <img> follows a sibling closing </div>.
The outer pattern uses ([\s\S]*?) (non-greedy), so the capture group ends at the first </div> in the content — not the matching closing tag for .hero-image. Any <img> that appears after a nested sibling div closes is outside the captured group and never seen by the inner img regex.
Failing structure (extremely common):
<div class="hero-image">
<div class="caption">Some caption</div>
<img src="hero.jpg"> ← missed: comes after first </div>
</div>A simpler, more robust approach: find the opening tag, then forward-scan for the first <img src> without trying to bound the search with a closing </div>:
🛠️ Proposed fix
function extractHeroImage(content: string): string | undefined {
- const heroContainerMatch = content.match(/<div[^>]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>([\s\S]*?)<\/div>/i);
- if (!heroContainerMatch?.[1]) {
- return undefined;
- }
- const imageMatch = heroContainerMatch[1].match(/<img[^>]*\bsrc=["']([^"']+)["'][^>]*>/i);
- return imageMatch?.[1];
+ const heroStart = content.search(/<div[^>]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>/i);
+ if (heroStart === -1) return undefined;
+ // Scan forward from the opening tag for the first <img src=...>
+ const afterOpen = content.slice(heroStart);
+ const imageMatch = afterOpen.match(/<img[^>]*\bsrc=["']([^"']+)["'][^>]*>/i);
+ return imageMatch?.[1];
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@infra/website/src/pages/blog/`[slug].astro around lines 15 - 22, The
extractHeroImage function's outer regex uses a non-greedy capture up to the
first </div>, which misses an <img> that appears after a nested sibling closing
tag; change the logic to first locate the opening <div> with class "hero-image"
(match the opening tag only, e.g. via
/<div[^>]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>/i) then take the
substring starting after that opening-tag match and search forward for the first
<img ... src="..."> (e.g. use a second regex
/<img[^>]*\bsrc=["']([^"']+)["'][^>]*>/i on that substring) and return its src
if found; update extractHeroImage to implement this two-step search so
nested/sibling tags no longer cause the img to be missed.
| def _handle_scalar_map_value(value_map_message: ScalarMap) -> Dict[Any, Any]: | ||
| """Handle ScalarMap proto message (repeated ScalarMapEntry) → Python dict.""" | ||
| result: Dict[Any, Any] = {} | ||
| for entry in value_map_message.val: | ||
| key = _map_key_to_python_value(entry.key) | ||
| value = feast_value_type_to_python_type(entry.value) | ||
| result[key] = value | ||
| return result |
There was a problem hiding this comment.
Detect Python-key collisions when decoding ScalarMap to prevent silent data loss.
Line 264 writes directly into a Python dict; distinct proto keys like bool_key=true and int64_key=1 collapse to one Python key (True == 1), silently overwriting one entry.
Proposed fix
def _handle_scalar_map_value(value_map_message: ScalarMap) -> Dict[Any, Any]:
"""Handle ScalarMap proto message (repeated ScalarMapEntry) → Python dict."""
result: Dict[Any, Any] = {}
for entry in value_map_message.val:
key = _map_key_to_python_value(entry.key)
value = feast_value_type_to_python_type(entry.value)
+ if key in result:
+ raise ValueError(
+ f"SCALAR_MAP key collision after Python conversion for key={key!r}. "
+ "This can happen for semantically distinct proto keys (e.g., bool vs int)."
+ )
result[key] = value
return result🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sdk/python/feast/type_map.py` around lines 258 - 265, When decoding ScalarMap
in _handle_scalar_map_value, detect Python-key collisions produced by
_map_key_to_python_value (e.g., True == 1) instead of silently overwriting:
before assigning result[key] = value, check if key is already present in result
and if so raise a clear exception (e.g., ValueError) that includes both the
conflicting proto entry information and the existing key/value to prevent silent
data loss; update any callers/tests accordingly to expect this failure mode.
| "decimal_val": ValueType.DECIMAL, | ||
| "decimal_list_val": ValueType.DECIMAL_LIST, | ||
| "decimal_set_val": ValueType.DECIMAL_SET, | ||
| "scalar_map_val": ValueType.SCALAR_MAP, |
There was a problem hiding this comment.
SCALAR_MAP registration is incomplete across type-conversion helpers.
Line 1426 adds proto mapping, but feast_value_type_to_pandas_type() and _convert_value_type_str_to_value_type() do not include SCALAR_MAP, causing wrong fallback behavior (TypeError/STRING) in reachable conversion paths.
Proposed fix
def feast_value_type_to_pandas_type(value_type: ValueType) -> Any:
@@
- if (
- value_type.name in ("MAP", "JSON", "STRUCT", "VALUE_LIST", "VALUE_SET")
+ if (
+ value_type.name in ("MAP", "SCALAR_MAP", "JSON", "STRUCT", "VALUE_LIST", "VALUE_SET")
or value_type.name.endswith("_LIST")
or value_type.name.endswith("_SET")
):
return "object"
@@
def _convert_value_type_str_to_value_type(type_str: str) -> ValueType:
type_map = {
@@
"DECIMAL": ValueType.DECIMAL,
"DECIMAL_LIST": ValueType.DECIMAL_LIST,
"DECIMAL_SET": ValueType.DECIMAL_SET,
+ "SCALAR_MAP": ValueType.SCALAR_MAP,
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sdk/python/feast/type_map.py` at line 1426, Add explicit handling for
SCALAR_MAP in both conversion helpers: update feast_value_type_to_pandas_type to
include a branch mapping ValueType.SCALAR_MAP to an appropriate pandas dtype
(e.g., pandas.ObjectDtype or pandas dtype 'object') instead of falling back, and
update _convert_value_type_str_to_value_type to recognize the string key used in
the proto mapping ("scalar_map_val") and return ValueType.SCALAR_MAP. Modify the
code inside the functions feast_value_type_to_pandas_type and
_convert_value_type_str_to_value_type to include these new cases so SCALAR_MAP
no longer hits the TypeError/STRING fallback.
| Uuid = PrimitiveFeastType.UUID | ||
| TimeUuid = PrimitiveFeastType.TIME_UUID | ||
| Decimal = PrimitiveFeastType.DECIMAL | ||
| ScalarMap = PrimitiveFeastType.SCALAR_MAP |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n "SCALAR_MAP" --type py sdk/python/feast/type_map.pyRepository: opendatahub-io/feast
Length of output: 392
🏁 Script executed:
#!/bin/bash
# Get context around line 1114 and nearby lines to identify the function
sed -n '1100,1150p' sdk/python/feast/type_map.py | cat -n
# Also check what function contains line 446
sed -n '430,460p' sdk/python/feast/type_map.py | cat -nRepository: opendatahub-io/feast
Length of output: 3758
🏁 Script executed:
#!/bin/bash
# Search for feast_value_type_to_pa function definition
rg -n "def.*feast_value_type_to_pa|def.*to_pa|def.*to_arrow|def.*to_pyarrow" --type py sdk/python/feast/type_map.py | head -20Repository: opendatahub-io/feast
Length of output: 218
🏁 Script executed:
#!/bin/bash
# Get context around the feast_value_type_to_pa function (line 1949)
sed -n '1949,2050p' sdk/python/feast/type_map.py | cat -nRepository: opendatahub-io/feast
Length of output: 4864
🏁 Script executed:
#!/bin/bash
# Search for calls to feast_value_type_to_pa in the codebase
rg -n "feast_value_type_to_pa" --type py sdk/python/feast/ | head -30Repository: opendatahub-io/feast
Length of output: 1232
🏁 Script executed:
#!/bin/bash
# Also check FEAST_TYPES_TO_PYARROW_TYPES in types.py
rg -n "FEAST_TYPES_TO_PYARROW_TYPES" --type py sdk/python/feast/types.py -A 30 | head -50Repository: opendatahub-io/feast
Length of output: 2283
🏁 Script executed:
#!/bin/bash
# Check the error at line 422 in types.py
sed -n '385,430p' sdk/python/feast/types.py | cat -nRepository: opendatahub-io/feast
Length of output: 2254
🏁 Script executed:
#!/bin/bash
# Check line 290 context in offline_utils.py to confirm SCALAR_MAP would hit this code
sed -n '280,300p' sdk/python/feast/infra/offline_stores/offline_utils.py | cat -nRepository: opendatahub-io/feast
Length of output: 1172
🏁 Script executed:
#!/bin/bash
# Verify that SCALAR_MAP can actually appear in batch source types
# Check if there are tests or examples of SCALAR_MAP being used
rg -n "SCALAR_MAP" --type py sdk/python/feast/ | grep -i "test\|example" | head -20Repository: opendatahub-io/feast
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Search for test files that reference SCALAR_MAP
find sdk/python -name "*test*.py" -type f | xargs rg -l "SCALAR_MAP" | head -10Repository: opendatahub-io/feast
Length of output: 103
🏁 Script executed:
#!/bin/bash
# Check if ScalarMap appears in types.py as a type alias like the review shows
sed -n '90,160p' sdk/python/feast/types.py | cat -nRepository: opendatahub-io/feast
Length of output: 2286
🏁 Script executed:
#!/bin/bash
# Check the test file for SCALAR_MAP tests
rg -n "SCALAR_MAP\|ScalarMap" --type py sdk/python/tests/unit/test_type_map.py -B 2 -A 5Repository: opendatahub-io/feast
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Check what tests exist in test_type_map.py
rg -n "def test_" --type py sdk/python/tests/unit/test_type_map.py | head -20Repository: opendatahub-io/feast
Length of output: 1080
🏁 Script executed:
#!/bin/bash
# Check if feast_value_type_to_pa is tested at all
rg -n "feast_value_type_to_pa" --type py sdk/python/tests/unit/test_type_map.pyRepository: opendatahub-io/feast
Length of output: 1880
🏁 Script executed:
#!/bin/bash
# Check if there's a test for SCALAR_MAP in test_type_map.py at all
rg -n "SCALAR_MAP\|scalar_map\|ScalarMap" --type py sdk/python/tests/unit/test_type_map.pyRepository: opendatahub-io/feast
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Check if SCALAR_MAP is supposed to be limited/not used yet
rg -n "SCALAR_MAP" --type py sdk/python/feast/ -B 1 -A 1 | grep -i "todo\|fixme\|deprecated\|not.*supported\|not.*implemented" -B 3 -A 1Repository: opendatahub-io/feast
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Check what actually calls feast_value_type_to_pa at line 290 in offline_utils.py
# and trace if SCALAR_MAP could realistically reach that code
sed -n '270,310p' sdk/python/feast/infra/offline_stores/offline_utils.py | cat -nRepository: opendatahub-io/feast
Length of output: 2111
SCALAR_MAP missing from PyArrow type mappings — feast_value_type_to_pa(ValueType.SCALAR_MAP) raises KeyError.
SCALAR_MAP is registered for proto serialization and type inference but absent from both PyArrow conversion paths:
-
type_map.py(line 1949):feast_value_type_to_pa()type_map dict lacksValueType.SCALAR_MAP; line 46 raisesKeyErrorwhen called withSCALAR_MAP. This function is actively used in offline store schema resolution (offline_utils.py:290). -
types.py(line 356–370):FEAST_TYPES_TO_PYARROW_TYPESdict lacksScalarMapentry.from_feast_to_pyarrow_type(ScalarMap)falls through toValueErrorat line 422.
No test coverage exists for either conversion path. Any feature with SCALAR_MAP type in an offline store query or batch materialization will crash at runtime.
Add SCALAR_MAP to both mappings:
# type_map.py, line ~1949 type_map dict
ValueType.SCALAR_MAP: pyarrow.binary(), # serialized proto; preserves key type info
# types.py, line ~356 FEAST_TYPES_TO_PYARROW_TYPES dict
ScalarMap: pyarrow.binary(),Add test:
def test_feast_value_type_to_pa_scalar_map(self):
pa_type = feast_value_type_to_pa(ValueType.SCALAR_MAP)
assert pa_type == pyarrow.binary()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sdk/python/feast/types.py` at line 135, The SCALAR_MAP Feast type is not
mapped to PyArrow causing KeyError/ValueError; add ValueType.SCALAR_MAP:
pyarrow.binary() to the type_map dict used by feast_value_type_to_pa
(type_map.py) and add ScalarMap: pyarrow.binary() to
FEAST_TYPES_TO_PYARROW_TYPES in types.py (ScalarMap is defined as
PrimitiveFeastType.SCALAR_MAP), then add a unit test named
test_feast_value_type_to_pa_scalar_map that calls
feast_value_type_to_pa(ValueType.SCALAR_MAP) and asserts the result equals
pyarrow.binary().
| def test_empty_value_map(self): | ||
| """Empty dict encodes and decodes as empty SCALAR_MAP.""" | ||
| protos = python_values_to_proto_values([{}], ValueType.SCALAR_MAP) | ||
| # empty dict has no non-string key to trigger SCALAR_MAP via inference, | ||
| # but explicit type forces the path | ||
| result = feast_value_type_to_python_type(protos[0]) | ||
| assert isinstance(result, dict) |
There was a problem hiding this comment.
test_empty_value_map — add assertion that the proto field is set and the result is empty.
The test only checks isinstance(result, dict) but doesn't verify:
- That the encoder actually set
scalar_map_val(not an emptyProtoValue()), otherwisefeast_value_type_to_python_typereturnsNoneand the assert would fail silently if the test is skipped. - That the decoded dict is actually empty.
🔧 Proposed fix
def test_empty_value_map(self):
"""Empty dict encodes and decodes as empty SCALAR_MAP."""
protos = python_values_to_proto_values([{}], ValueType.SCALAR_MAP)
- # empty dict has no non-string key to trigger SCALAR_MAP via inference,
- # but explicit type forces the path
result = feast_value_type_to_python_type(protos[0])
+ assert protos[0].WhichOneof("val") == "scalar_map_val"
assert isinstance(result, dict)
+ assert len(result) == 0🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sdk/python/tests/unit/test_type_map.py` around lines 2026 - 2032, In
test_empty_value_map, ensure the encoded proto actually set the scalar_map field
and the decoded result is empty: after calling
python_values_to_proto_values([{}], ValueType.SCALAR_MAP) assert that
protos[0].WhichOneof('val') == 'scalar_map_val' (or that
protos[0].scalar_map_val is not an empty/default ProtoValue) and then assert
that feast_value_type_to_python_type(protos[0]) == {} to verify the decoded dict
is empty; keep the existing isinstance check if desired but add these two
explicit assertions to validate both encoding and decoding.
|
@ntkathole: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jyejare, ntkathole, Srihari1192 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What this PR does / why we need it:
Fix for https://github.com/red-hat-data-services/rhods-devops-infra/actions/runs/25529907815/job/74933758135
Summary by CodeRabbit
New Features
Documentation
Chores