Skip to content

fix(cache): skip non-file source_file in save_semantic_cache#444

Closed
rashikkathuria wants to merge 1 commit into
Graphify-Labs:v4from
rashikkathuria:rashik/cache-skip-directory-source-file
Closed

fix(cache): skip non-file source_file in save_semantic_cache#444
rashikkathuria wants to merge 1 commit into
Graphify-Labs:v4from
rashikkathuria:rashik/cache-skip-directory-source-file

Conversation

@rashikkathuria

Copy link
Copy Markdown

Summary

save_semantic_cache aborts a whole batch with IsADirectoryError when a subagent emits a node whose source_file happens to be a directory path instead of a file. Observed on a TS/NestJS corpus where a subagent attributed an abstract base to src/common/database/abstracts/mongo/repositories (the containing folder). save_cached → file_hash → read_bytes then crashes, so every other file in the batch fails to cache too.

This PR makes the save path tolerant:

  • save_cached(path, ...) now no-ops when path is not a regular file.
  • save_semantic_cache(...) uses p.is_file() instead of p.exists() so directories are silently skipped.

Real files in the same batch cache normally; the bogus entry is just dropped.

Changes

  • graphify/cache.py — 2 small defensive checks, docstring explaining the case.
  • tests/test_cache.py — 3 new tests:
    • test_save_cached_noop_on_directory
    • test_save_semantic_cache_skips_directory_source_file (mixed batch: real file + directory)
    • test_save_semantic_cache_skips_missing_file

Test plan

  • pytest tests/test_cache.py — 15/15 pass (12 existing + 3 new)
  • Reproduced original bug on a 288-file NestJS corpus (22-file chunk aborted mid-save)
  • Verified patched version caches all files in the same corpus

Subagent-produced semantic fragments occasionally set source_file to a
directory path instead of a file (e.g. an abstract base the model
attributed to a folder). save_cached then crashes on file_hash ->
read_bytes with IsADirectoryError (errno 21), aborting the whole batch
and leaving partial cache state.

save_cached now no-ops on non-file paths; save_semantic_cache uses
is_file() instead of exists() so directory entries are silently skipped.
Real files in the same batch still cache normally.

Adds 3 tests covering directory, missing-file, and mixed-batch cases.
safishamsi added a commit that referenced this pull request Apr 21, 2026
- cache: skip directory source_file in save_cached to prevent IsADirectoryError (#444)
- report: skip structural-only communities with no real nodes (#443)
- hooks: allow @ in python path allowlist for Homebrew paths (#474)
- watch: keep source_file paths project-relative after rebuild (#434)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@safishamsi

Copy link
Copy Markdown
Collaborator

Thanks for the detailed fix and tests! Implemented directly in v0.4.24 — the save_cached directory guard and test coverage are in.

@safishamsi safishamsi closed this Apr 21, 2026
safishamsi added a commit that referenced this pull request Apr 23, 2026
- cache: skip directory source_file in save_cached to prevent IsADirectoryError (#444)
- report: skip structural-only communities with no real nodes (#443)
- hooks: allow @ in python path allowlist for Homebrew paths (#474)
- watch: keep source_file paths project-relative after rebuild (#434)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
matzls pushed a commit to matzls/graphify that referenced this pull request May 10, 2026
- cache: skip directory source_file in save_cached to prevent IsADirectoryError (Graphify-Labs#444)
- report: skip structural-only communities with no real nodes (Graphify-Labs#443)
- hooks: allow @ in python path allowlist for Homebrew paths (Graphify-Labs#474)
- watch: keep source_file paths project-relative after rebuild (Graphify-Labs#434)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants