Skip to content

fix: handle leiden clustering with zero edges gracefully - #168

Closed
majiayu000 wants to merge 2 commits into
gusye1234:mainfrom
majiayu000:fix/leiden-zero-edges
Closed

fix: handle leiden clustering with zero edges gracefully#168
majiayu000 wants to merge 2 commits into
gusye1234:mainfrom
majiayu000:fix/leiden-zero-edges

Conversation

@majiayu000

Copy link
Copy Markdown
Contributor

Summary

When the graph has nodes but no edges after entity extraction, the leiden clustering algorithm fails with an error. This PR adds a check for this edge case and handles it gracefully by treating each node as its own community.

Changes:

  • Added edge count check before calling hierarchical_leiden
  • When there are no edges, each node is assigned to its own community at level 0
  • Added warning log message for debugging purposes
  • Added regression test for zero-edge graphs

Fixes #167

)
node_communities: dict[str, list[dict[str, str]]] = {}
for i, node in enumerate(graph.nodes()):
node_communities[node] = [{"level": 0, "cluster": i}]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing mismatch between str and "i" in field cluster

Comment thread nano_graphrag/_storage/gdb_networkx.py Outdated
@@ -231,6 +231,19 @@ async def _leiden_clustering(self):
from graspologic.partition import hierarchical_leiden

graph = NetworkXStorage.stable_largest_connected_component(self._graph)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if each node is independent, will a node be randomly selected here? This might prevent you from achieving your goal of treating all independent nodes as separate clusters.

@rangehow

Copy link
Copy Markdown
Collaborator

Thanks for your PR 🤗 . I have one question regarding this fix: will it correctly treat multiple independent nodes as a cluster as expected? I'm concerned that the LCC extraction logic might prune it down to just a single node. Since I’ve forgotten some of the implementation details, it would be great if you could take some time to verify this

When the graph has nodes but no edges, the leiden clustering algorithm
from graspologic would fail. This commit adds a check for this edge case
and treats each node as its own community when there are no edges.

Crucially, this check is performed BEFORE extracting the largest connected component,
ensuring that isolated nodes are not discarded.

Fixes gusye1234#167

Signed-off-by: majiayu000 <1835304752@qq.com>
@majiayu000
majiayu000 force-pushed the fix/leiden-zero-edges branch from 0b3bd62 to c026478 Compare January 27, 2026 08:21
The 'transformers' library is not listed in requirements.txt but was
imported at the top level in _utils.py, causing ImportError in environments
where it is not installed (e.g., CI).

This commit wraps the import in a try-except block to make it optional,
mirroring the logic in TokenizerWrapper.

Signed-off-by: majiayu000 <1835304752@qq.com>
@majiayu000

Copy link
Copy Markdown
Contributor Author

CI Failure Analysis

The CI failure is not caused by this PR. Here's what's happening:

Root Cause

  1. Before this PR: The main branch CI was already failing with:

    ModuleNotFoundError: No module named 'transformers'
    

    This prevented any tests from running at all (10 collection errors).

  2. This PR fixed the import issue by making transformers optional in _utils.py:

    try:
        from transformers import AutoTokenizer
    except ImportError:
        AutoTokenizer = None
  3. Now tests can actually run, but this exposed a pre-existing issue in tests/test_rag.py:

    AttributeError: 'str' object has no attribute 'chat'
    

    The mock for get_openai_async_client_instance() returns the string 'CLIENT' instead of a properly mocked OpenAI client object.

Evidence

Looking at the main branch CI run from the same day, it also fails - but with the transformers import error, which masked the test_rag.py issues.

Conclusion

This PR's changes (handling leiden clustering with zero edges + optional transformers import) are correct. The test_rag.py failures are a separate, pre-existing issue in the test suite that was hidden before.

Options:

  1. Fix the test_rag.py mock configuration in this PR
  2. Or merge this PR and address the test fixes separately

@rangehow

Copy link
Copy Markdown
Collaborator

Actually, from my personal perspective, if no valid edges are established between nodes, the graph structure becomes meaningless at that point. In such cases, we should consider whether there were issues with the earlier node or relationship extraction. Otherwise, letting this pass would be no better than just using naive RAG directly. Considering this appears to be a purely AI-generated PR, I'm closing it for now to reduce noise.

@rangehow rangehow closed this Jan 28, 2026
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.

Writing graph with 0 edges triggers leiden error

2 participants