Skip to content

[Bug] handle_multiple_group_ids raises TypeError: got multiple values for argument when group_ids and driver are both passed positionally with >1 group_id #1758

Description

@C-Bjorn

[Bug] handle_multiple_group_ids raises TypeError: got multiple values for argument when group_ids and driver are both passed positionally with >1 group_id

Summary

handle_multiple_group_ids (graphiti_core/decorators.py)'s multi-group_id
branch rebuilds the call for each group as:

filtered_args = list(args)
if group_ids_pos is not None and len(args) > group_ids_pos:
    filtered_args.pop(group_ids_pos)

return await func(
    self, *filtered_args,
    **{**kwargs, 'group_ids': [gid], 'driver': driver.clone(database=gid)},
)

This only removes group_ids from the positional slot it occupied in the
original call. If the caller also passed driver positionally (which is
legal — driver is a normal positional-or-keyword parameter on every
decorated method, e.g. Graphiti.build_communities(self, group_ids=None, driver=None)), the remaining positional arguments shift down by one slot
when func is re-invoked. The shifted argument then collides with a
parameter name the wrapper also injects as a kwarg (group_ids or driver,
depending on their relative order in the signature), raising a TypeError
before the wrapped method's body ever runs.

This is a different defect from #1659 (single-group_id FalkorDB routing,
already fixed on main) — it affects the multi-group_id branch and is not
covered by the existing test suite (tests/test_handle_multiple_group_ids.py
only exercises keyword-argument calls).

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation

Objective

Fix handle_multiple_group_ids's multi-group_id branch to bind arguments by
name (e.g. via inspect.signature(func).bind(...) or by always passing
group_ids/driver as keyword-only within the wrapper) instead of relying
on raw positional-list surgery, so callers who pass group_ids and/or
driver positionally don't hit an argument-binding collision.

What I was trying to do

Call a handle_multiple_group_ids-decorated method with more than one
group_id, passing both group_ids and driver positionally — a pattern
the real method signatures allow since both are ordinary
positional-or-keyword parameters.

What I expected

The call to route per-group_id and merge results, the same as it does when
group_ids is passed as a keyword argument.

What actually happened

TypeError: Graphiti.build_communities() got multiple values for argument 'group_ids'

raised from inside the decorator's execute_for_group helper, before
build_communities's body runs.

Reproduction

Exercised directly against the real, unmodified Graphiti.build_communities:

from types import SimpleNamespace
from graphiti_core.driver.driver import GraphProvider
from graphiti_core.graphiti import Graphiti

class _FakeDriver:
    provider = GraphProvider.FALKORDB
    _database = 'reggraph'
    def clone(self, database):
        clone = _FakeDriver()
        clone._database = database
        return clone

async def main():
    g = Graphiti.__new__(Graphiti)  # bypass __init__; no LLM/DB needed
    driver = _FakeDriver()
    g.clients = SimpleNamespace(driver=driver)
    g.max_coroutines = None
    # Real signature: build_communities(self, group_ids=None, driver=None)
    result = await g.build_communities(['a', 'b'], driver)
    print('result:', result)

import asyncio; asyncio.run(main())

Actual output against main:

TypeError: Graphiti.build_communities() got multiple values for argument 'group_ids'

The TypeError occurs during argument binding inside the decorator, before
any driver I/O — no live database connection is required to demonstrate the
collision, though the finding was cross-checked against a disposable
FalkorDB-shaped fake to confirm the is_falkor / multi-group branch is what
gets exercised.

On the use of Graphiti.__new__ and a stub driver: a fully-constructed
Graphiti would require a live FalkorDB instance and a configured LLM client,
neither of which the failure depends on — the TypeError is raised while
binding arguments, before the decorated method's body runs and before any
connection is opened, so the object's remaining state is never reached. The
stub supplies only provider and clone(), which are the two attributes the
decorator itself touches on the multi-group path. Happy to provide an
equivalent reproduction against a real FalkorDB instance and LLM client if
that would be more useful for triage.

Testing

Reproduced against the real Graphiti.build_communities method (not a
stand-in). tests/test_handle_multiple_group_ids.py's existing four tests
all call the decorated function with group_ids as a keyword argument, so
none of them exercise this path. A fix should add a test calling with both
group_ids and driver positional, multiple group_ids, and assert no
TypeError.

Breaking Changes

None expected — the fix only needs to change how the wrapper re-invokes
func internally (bind-by-name instead of positional-list surgery); the
decorator's external calling contract is unchanged.

Checklist

Related Issues

Distinct from #1659 (single-group_id FalkorDB routing, already fixed on
main). No existing issue found covering this positional-argument collision
in the multi-group_id branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions