quick-cartoon-22764
03/12/2026, 5:17 PMtall-airline-16756
03/12/2026, 5:17 PMtall-airline-16756
03/12/2026, 5:18 PMend_call includes a required list but does not define a properties object. JSON Schema validation requires that if you list required fields, you must also declare those fields in properties.
What I’m responding to: the error you posted: livekit.agents._exceptions.APIStatusError: ... "invalid JSON schema for tool end_call, tools[2].function.parameters: 'required' present but 'properties' is missing"
What you can do (quick fixes)
• If the tool expects arguments: add a properties object that defines each required field and keep required. Example:
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for ending the call"
}
},
"required": ["reason"]
}
• If the tool should take no arguments: remove required (and you can leave properties empty) — for example:
"parameters": {
"type": "object",
"properties": {}
}
If you’re using a decorator like @function_tool with raw_schema, ensure parameters follows the same structure (include properties when you list required).
To help further, please share one of these:
• The exact `parameters`/raw schema you currently use for end_call, or
• The code snippet where you define the tool (the @function_tool block or equivalent).
I can then point out the precise change to make or provide a corrected snippet.
Sources: Function tool definition | LiveKit Documentationquick-cartoon-22764
03/12/2026, 5:20 PM@function_tool()
async def end_call(self,
ctx: RunContext):
"""Called when the agents has collected all information and is ready to end the call."""
<http://log.info|log.info>(f"[{self.agent_name}][correlation_id: {self.room_name}]: Ending the call")
# await self.session.say(text=f"{message}")
await ctx.wait_for_playout()
await asyncio.sleep(0.5)
self.disconnectedBy = 'Bot'
await self.hangup()tall-airline-16756
03/12/2026, 5:20 PMend_call implementation is an argument-less async function, which means your tool schema should either declare no required parameters or include an empty properties object. The JSON schema validation error happened because required was present in the tool definition but properties was missing.
Two ways to fix this depending on how you register the tool:
1) If you register the tool with no parameters (recommended here)
• Remove any required from the tool's parameters schema and set properties to an empty object.
Example using raw_schema (or the decorator that accepts schema):
@function_tool(raw_schema={
"name": "end_call",
"description": "End the current call.",
"parameters": {
"type": "object",
"properties": {}
}
})
async def end_call(self, ctx: RunContext):
# your existing implementation
<http://log.info|log.info>(f"[{self.agent_name}][correlation_id: {self.room_name}]: Ending the call")
await ctx.wait_for_playout()
await asyncio.sleep(0.5)
self.disconnectedBy = 'Bot'
await self.hangup()
2) If you want the tool to accept parameters (for example a reason)
• Define properties and required to match the expected fields.
Example:
@function_tool(raw_schema={
"name": "end_call",
"description": "End the current call.",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for ending the call"
}
},
"required": ["reason"]
}
})
async def end_call(self, ctx: RunContext, reason: str = None):
<http://log.info|log.info>(f"[{self.agent_name}][correlation_id: {self.room_name}]: Ending the call: {reason}")
await ctx.wait_for_playout()
await asyncio.sleep(0.5)
self.disconnectedBy = 'Bot'
await self.hangup()
Which option fits you?
• If end_call should have no arguments, use option 1.
• If you need arguments (like reason), use option 2 and adjust the function signature to accept them.
If you share how you currently register the tool (the decorator call or the tool list where end_call is defined), I’ll provide the exact corrected snippet to paste in.quick-cartoon-22764
03/12/2026, 5:22 PMtall-airline-16756
03/12/2026, 5:22 PMfunction_tool (or otherwise register it as a callable tool for the model), its parameters schema must be a valid JSON Schema object. Concretely:
• If you include a required array, you must also include a properties object that lists the required fields.
• If the function takes no arguments, omit required and either include an empty properties object or no parameters block at all (depending on your tool registration method).
What this looks like in practice
• No-argument tool (recommended for your current end_call):
@function_tool(raw_schema={
"name": "end_call",
"description": "End the current call.",
"parameters": {
"type": "object",
"properties": {}
}
})
async def end_call(self, ctx: RunContext):
# your implementation
• Tool with arguments (only if you need them):
@function_tool(raw_schema={
"name": "end_call",
"description": "End the current call.",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for ending the call"
}
},
"required": ["reason"]
}
})
async def end_call(self, ctx: RunContext, reason: str):
# handle reason
Quick checklist to avoid the JSON schema error you saw
• Do not list fields in required unless they are defined under properties.
• Ensure parameters is an object with "type": "object" when using properties/required.
• If you register tools in a list (not via decorator), check that each tool’s function.parameters follows the same rules.
If you want, paste the decorator or the tool registration snippet you currently use (the @function_tool(...) call or the tool list) and I’ll give the exact corrected schema to paste in.