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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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