[Bug]: MediaResource.hash is platform-dependent for paths — test_hash fails on Windows
Bug Description
MediaResource.hash hashes the path via str(self.path), which embeds the OS path separator. The same logical path therefore produces a different hash on Windows than on Linux/macOS:
- str(Path("foo/bar/baz")) → foo/bar/baz on POSIX
- str(Path("foo/bar/baz")) → foo\bar\baz on Windows
Because Node.hash aggregates the resource hashes (llama-index-core/llama_index/core/schema.py:752-762), any node holding a resource with a path — for example ImageDocument(image_path=...), whose setter builds MediaResource(path=Path(image_path)) at schema.py:1377 — gets a different hash depending on the operating system.
This is not a cosmetic value. MediaResource.hash feeds deduplication and change detection during ingestion (llama_index/core/ingestion/pipeline.py:462, llama_index/core/indices/base.py:446, llama_index/core/indices/property_graph/base.py:248). A hash that varies by platform means the same corpus ingested on Windows and on Linux produces different node hashes, so a persisted docstore built on one platform does not line up with the other.
It also makes the committed test tests/schema/test_media_resource.py::test_hash fail on Windows, because its expected constant was generated on POSIX. The suite only runs on ubuntu in CI (.github/workflows/unit_test.yml uses an ubuntu runner; .github/workflows/build_package.yml does run on windows-latest but only builds the wheel and imports the package — it never runs pytest), so this has been invisible.
Note that the same file already normalises paths with as_posix() at schema.py:872 in ImageNode.init, which makes MediaResource.hash the inconsistent one.
Proposed fix
bits.append(str(sha256(self.path.as_posix().encode("utf-8")).hexdigest()))
On POSIX nothing changes, since as_posix() == str() there. On Windows the hash changes, so a Windows user with an existing persisted docstore would re-ingest once. I am opening this issue before the PR because that consequence is worth a maintainer's opinion first — if you would rather keep the native path in the hash and instead make the test platform-aware, that is a reasonable alternative and I am happy to take that direction.
I have a patch ready and verified locally; I will link the PR here once you have had a look.
Version
0.14.24
Steps to Reproduce
On Windows:
git clone https://github.com/run-llama/llama_index
cd llama_index/llama-index-core
uv run -- pytest tests/schema/test_media_resource.py::test_hash -q
The test fails. It passes on Linux and macOS.
Relevant Logs/Tracebacks
AssertionError: assert '42ba2cae6741...dfa5828c9ac90' == '04414a5f03ad...1ecbd54ab4909'
- 04414a5f03ad7fa055229b4d3690d47427cb0b65bc7eb8f770d1ecbd54ab4909
- 42ba2cae6741bdc5c60d02ff18c4cae8b5a5d2d946219a7df4fdfa5828c9ac90
llama-index-core/tests/schema/test_media_resource.py:46: AssertionError
str(path): 'foo\bar\baz'
path.as_posix():'foo/bar/baz'
observed hash:42ba2cae6741bdc5c60d02ff18c4cae8b5a5d2d946219a7df4fdfa5828c9ac90
test expectation:04414a5f03ad7fa055229b4d3690d47427cb0b65bc7eb8f770d1ecbd54ab4909
hash with as_posix() instead of str(path):04414a5f03ad7fa055229b4d3690d47427cb0b65bc7eb8f770d1ecbd54ab4909 <- matches
Source: run-llama/llama_index