Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Tool argument errors put the argument values in the log message body, outside `lk.pii.*`

Abierto
#7,801 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Li-john1021 ya está trabajando en esto.

Desde el 14/10/2026.

  • #7804 de @Li-john1021 — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
Medio día
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python

Línea de trabajo

The message comes from prepare_function_arguments in livekit/agents/llm/utils.py, and the warning is logged in perform_tool_executions in voice/generation.py. Read telemetry/traces.py to see how lk.pii. fields are handled. Done means the ToolError warning logs a static message with the error text under a lk.pii. key. Pull request #7804 is already open against this issue, so check it before starting.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Bug Description

When a tool call's arguments can't be prepared, prepare_function_arguments raises a ToolError whose message includes the arguments:

  • a validation error (valid JSON, wrong type) embeds the pydantic error text, which includes input_value=... (code)
  • JSON that json_repair can't recover embeds the first 200 characters of the raw arguments (code, re-raised at L687)

perform_tool_executions then logs that message in the body of ToolError while executing tool: %s (code).

The same failure is also logged as error parsing arguments for ... with the arguments in lk.pii.arguments, so the value is marked there. The ToolError warning has no lk.pii. field, so the value is in the body, where it can't be dropped ("a log body cannot be redacted", traces.py). This is the same class as #7156 (participant identity in log bodies), at a call site that PR doesn't touch.

Expected Behavior

The argument values are not in the log body. For example, the warning logs a static message and puts the error text under a lk.pii. key, as error parsing arguments for ... already does. The ToolError returned to the model can keep the detail.

Reproduction Steps

Only livekit-agents, no audio or network. A scripted LLM returns one tool call, then a text reply, and the logs go through the CLI's JsonFormatter.

SECRET = "[email protected]"

@function_tool
async def lookup_orders(count: int) -> str:
    """Look up the customer's latest orders."""
    return "ok"

# scripted LLM: first chat() returns
#   FunctionToolCall(name="lookup_orders", arguments=json.dumps({"count": SECRET}), call_id="call_1")
# then a plain text reply
session = AgentSession(llm=ScriptedLLM())
await session.start(agent=Agent(instructions="test", tools=[lookup_orders]))
await session.run(user_input="show my orders")

Output (full script below):

== valid JSON, wrong type: '{"count": "[email protected]"}'
  [ERROR] 'error parsing arguments for `lookup_orders`'
      value in lk.pii.* fields: ['lk.pii.arguments'] | value in message body: False
  [WARNING] 'ToolError while executing tool: Error parsing arguments for `lookup_or'
      value in lk.pii.* fields: no | value in message body: True
== truncated JSON: '{"count": "[email protected]'
  [WARNING] 'repaired malformed function-call JSON arguments'
      value in lk.pii.* fields: ['lk.pii.raw_arguments', 'lk.pii.repaired'] | value in message body: False
  [ERROR] 'error parsing arguments for `lookup_orders`'
      value in lk.pii.* fields: ['lk.pii.arguments'] | value in message body: False
  [WARNING] 'ToolError while executing tool: Error parsing arguments for `lookup_or'
      value in lk.pii.* fields: no | value in message body: True

In the second case the SDK repairs the JSON, then validation fails the same way.

Full script
"""Minimal repro: a tool argument error puts the argument value in the log message body.

The SDK marks content-bearing log fields with an `lk.pii.` prefix so that redaction can drop them,
because a log body cannot be redacted. When a tool call's arguments fail validation (a string for an
`int` parameter), the pydantic error text, including `input_value=...`, goes into the ToolError
message. When the arguments are not valid JSON, the first 200 characters of the raw arguments go into
it. `voice/generation.py` then logs that message in the body of `ToolError while executing tool: %s`,
with no `lk.pii.` field, so dropping `lk.pii.*` does not remove the value.

Only livekit-agents is used (no audio, no network). A scripted LLM returns one tool call, then a plain
text reply. Logs are written with the CLI's JsonFormatter.

    pip install "livekit-agents==1.8.6"
    python repro.py
"""
import asyncio
import io
import json
import logging

from livekit.agents import Agent, AgentSession, function_tool, llm
from livekit.agents.cli.log import JsonFormatter
from livekit.agents.types import DEFAULT_API_CONNECT_OPTIONS

SECRET = "[email protected]"  # stands in for user data the model put in the arguments

CASES = {
    "valid JSON, wrong type": json.dumps({"count": SECRET}),
    "truncated JSON": '{"count": "' + SECRET,
}


class ScriptedLLM(llm.LLM):
    def __init__(self, arguments: str) -> None:
        super().__init__()
        self.calls = 0
        self.arguments = arguments

    def chat(self, *, chat_ctx, tools=None, conn_options=DEFAULT_API_CONNECT_OPTIONS, **kwargs):
        self.calls += 1
        return ScriptedStream(
            self, chat_ctx=chat_ctx, tools=tools or [], conn_options=conn_options, turn=self.calls
        )


class ScriptedStream(llm.LLMStream):
    def __init__(self, llm_, *, turn, **kwargs) -> None:
        super().__init__(llm_, **kwargs)
        self._turn = turn

    async def _run(self) -> None:
        if self._turn == 1:
            call = llm.FunctionToolCall(name="lookup_orders", arguments=self._llm.arguments, call_id="call_1")
            delta = llm.ChoiceDelta(role="assistant", tool_calls=[call])
        else:
            delta = llm.ChoiceDelta(role="assistant", content="Sorry, could you repeat that?")
        self._event_ch.send_nowait(llm.ChatChunk(id=f"chunk_{self._turn}", delta=delta))


@function_tool
async def lookup_orders(count: int) -> str:
    """Look up the customer's latest orders.

    Args:
        count: how many orders to return
    """
    return "ok"


async def run_case(name: str, arguments: str) -> None:
    print(f"== {name}: {arguments!r}")
    out = io.StringIO()
    handler = logging.StreamHandler(out)
    handler.setFormatter(JsonFormatter())
    root = logging.getLogger()
    root.handlers = [handler]
    root.setLevel(logging.INFO)

    session = AgentSession(llm=ScriptedLLM(arguments))
    await session.start(agent=Agent(instructions="test", tools=[lookup_orders]))
    await session.run(user_input="show my orders")
    await session.aclose()

    lines = [json.loads(line) for line in out.getvalue().splitlines()]
    for line in lines:
        if SECRET not in json.dumps(line):
            continue
        marked = [k for k, v in line.items() if k.startswith("lk.pii.") and SECRET in json.dumps(v)]
        in_body = SECRET in line.get("message", "")
        print(f"  [{line['level']}] {line['message'][:70]!r}")
        print(f"      value in lk.pii.* fields: {marked or 'no'} | value in message body: {in_body}")
    leaked = [line for line in lines if SECRET in line.get("message", "")]
    print(f"  records with the value in the message body: {len(leaked)}")


async def main() -> None:
    for name, arguments in CASES.items():
        await run_case(name, arguments)


asyncio.run(main())
Operating System

Windows 11

Models Used

None (scripted LLM). In a real call this needs the model to send arguments that fail validation, for example a customer's email or phone number in a field of another type.

Package Versions
livekit-agents==1.8.6
python==3.13

The same code is on main and in [email protected].

Additional Context

We drop lk.pii.* from our stdout logs before they reach CloudWatch. In the tool path, this warning is where we found the value still getting through.

Lenguaje dominante
Python
Estrellas
14.6k
Forks
3.9k
Merge medio
3 d 3 h
PR fusionados (30 d)
171

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de livekit/agents

Todos los issues de livekit/agents

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.