Skip to content

Python parser hangs on deeply chained method calls during definitions pass #710

Description

@Majiaozhen

Describe the bug

When indexing a Python project, the index_repository tool hangs indefinitely during the definitions pass. The process consumes massive CPU (800+ seconds) and memory (~1.4 GB) without producing any result, eventually hitting the MCP request timeout (300s).

To Reproduce

Create a Python file containing a deeply chained method call like the following (LangGraph StateGraph builder pattern):

def build_graph(saver):
    graph = (
        StateGraph(state_schema=State)
        .add_node("node_a", handler_a)
        .add_node("node_b", handler_b)
        .add_node("node_c", handler_c)
        .add_node("node_d", handler_d)
        .add_node("node_e", handler_e)
        .add_node("node_f", handler_f)
        .add_node("node_g", handler_g)
        .add_node("node_h", handler_h)
        .add_node("node_i", handler_i)
        .add_node("node_j", handler_j)
        .add_node("node_k", handler_k)
        .add_node("node_l", handler_l)
        .add_node("node_m", handler_m)
        .add_node("node_n", handler_n)
        .add_edge(START, "node_a")
        .add_conditional_edges(
            "node_a", route_fn,
            {
                "node_b": "node_b",
                "node_c": "node_c",
                "node_d": "node_d",
                "node_error": "node_error",
            })
        .add_conditional_edges(
            "node_b", interrupt_fn,
            {
                "node_interrupt": "node_interrupt_b",
                "node_next": "node_e",
            })
        .add_conditional_edges(
            "node_c", interrupt_fn,
            {
                "node_interrupt": "node_interrupt_c",
                "node_next": "node_f",
            })
        .add_conditional_edges(
            "node_d", interrupt_fn,
            {
                "node_interrupt": "node_interrupt_d",
                "node_next": "node_g",
            })
        .add_edge("node_interrupt_b", "node_b")
        .add_edge("node_interrupt_c", "node_c")
        .add_edge("node_interrupt_d", "node_d")
        .add_edge("node_e", END)
        .add_edge("node_f", END)
        .add_edge("node_g", END)
        .add_edge("node_error", END)
        .compile(checkpointer=saver, debug=True)
    )
    return graph

Then run:

codebase-memory-mcp cli index_repository '{"repo_path": "/path/to/project"}'

The pipeline output stops at:

level=info msg=pass.start pass=definitions files=N

and never proceeds to the next pass.

Binary-search isolation

I isolated the issue via binary search on the project files:

Test case Result
Single-file Python project (def hello()) 170 ms, OK
5 small Python files (<100 lines each) 508 ms, OK
8 Python files (excluding the problematic file) 616 ms, OK
Adding the file with build_graph (14 chained calls + 4 conditional edges) Hangs at definitions pass
Same file, first 50 lines only (no build_graph) OK
Same file, first 120 lines (includes build_graph) Hangs
Same file, build_graph body replaced with a comment OK

The hang is specifically triggered by the deeply nested method chain pattern (StateGraph(...).add_node(...).add_node(...).....add_conditional_edges(...).add_edge(...).....compile(...)) with ~65 levels of nesting.

Expected behavior

The parser should either:

  1. Handle deeply chained method calls without hanging, or
  2. Detect the timeout/complexity and skip the file with a warning rather than blocking the entire indexing pipeline.

Environment

  • codebase-memory-mcp version: 0.8.1
  • OS: Windows 10/11 (x64)
  • Total RAM: 16 GB
  • Memory budget reported by server: 8055 MB

Additional context

  • The structure pass completes fine (nodes and edges are extracted correctly).
  • Only the definitions pass hangs — suggesting the tree-sitter Python parser enters a pathological state on this AST pattern.
  • The same project indexes successfully when the problematic function body is removed or the chain is broken into separate assignment statements.
  • Workaround: break the chain into intermediate variables, e.g. g = g.add_node(...) repeated on separate lines.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memory

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions