Skip to content

[BUG]: before_tool callback's lowercase_value() silently does nothing — return value discarded and dict() would TypeError #2081

Description

@wi5nuu

Name of sample affected

python/agents/customer-service

Description of issue

The lowercase_value() function in customer_service/shared_libraries/callbacks.py (lines 96–106) contains two independent defects. Additionally, its only call site in before_tool() (line 113) discards the return value, making the intended lowercasing behavior ineffective.

Both issues were verified by executing the current implementation.

Bug 1 — Return Value Is Discarded (line 113)

The before_tool() callback contains:

def before_tool(tool, args, tool_context):
    # i make sure all values that the agent is sending to tools are lowercase
    lowercase_value(args)

lowercase_value(args) returns a transformed value, but the return value is ignored.

When args is a dictionary, the function returns a generator object. Since that generator is never consumed or assigned back to args, no transformation occurs and the original input remains unchanged.

Verified output:

After call: {'name': 'JOHN DOE', 'email': 'John@Example.COM'}

The values remain unchanged despite the comment indicating that inputs should be converted to lowercase.

Bug 2 — TypeError When the Dictionary Branch Is Evaluated (line 100)

The dictionary branch currently contains:

def lowercase_value(value):
    if isinstance(value, dict):
        return (dict(k, lowercase_value(v)) for k, v in value.items())

The expression:

dict(k, lowercase_value(v))

passes two positional arguments to dict(), which accepts at most one positional argument.

If the generator is consumed, execution fails with:

TypeError: dict expected at most 1 argument, got 2

The implementation appears intended to use a dictionary comprehension:

{k: lowercase_value(v) for k, v in value.items()}

Impact

Because before_tool() runs before every tool invocation in the customer-service agent, the intended recursive input normalization has never been applied.

Current behavior:

  • Dictionary values are not lowercased.
  • String values remain unchanged.
  • The lowercasing mechanism is effectively inactive.
  • Fixing only Bug 1 would expose Bug 2 and result in a runtime TypeError.

Environment

  • OS & Architecture: Windows 11 (amd64)
  • Python Version: 3.10 (verified)

Reproduction Steps

args = {"name": "JOHN DOE", "email": "John@Example.COM"}

def lowercase_value(value):
    if isinstance(value, dict):
        return (dict(k, lowercase_value(v)) for k, v in value.items())
    elif isinstance(value, str):
        return value.lower()
    elif isinstance(value, (list, set, tuple)):
        tp = type(value)
        return tp(lowercase_value(i) for i in value)
    else:
        return value

# Bug 1: return value discarded
lowercase_value(args)
print("After call:", args)

# Bug 2: consuming the generator triggers TypeError
result = lowercase_value(args)

try:
    list(result)
except TypeError as e:
    print("TypeError:", e)

Actual Output

After call: {'name': 'JOHN DOE', 'email': 'John@Example.COM'}
TypeError: dict expected at most 1 argument, got 2

Expected Behavior

Input values should be recursively converted to lowercase before tool execution.

For example:

{
    "name": "john doe",
    "email": "john@example.com"
}

Affected File

customer_service/shared_libraries/callbacks.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions