Skip to content

Commit e261924

Browse files
fix(core): improve error message for missing title in JSON schema functions (#34683)
Changes Created I have fixed the issue where a generic and misleading error message was displayed when a JSON schema was missing the top-level title key. [Fix: Improve error message for missing title in JSON schema functions](https://github.com/Bhavesh007Sharma/langchain/tree/fix-json-schema-title-error) File Modified: libs/core/langchain_core/utils/function_calling.py I updated the convert_to_openai_function validation logic to specifically check for dict inputs that look like schemas ( type or properties keys present) but are missing the title key. # Before (Generic Error) raise ValueError( f"Unsupported function\n\n{function}\n\nFunctions must be passed in" " as Dict, pydantic.BaseModel, or Callable. If they're a dict they must" " either be in OpenAI function format or valid JSON schema with top-level" " 'title' and 'description' keys." ) # After (Specific Error) if isinstance(function, dict) and ("type" in function or "properties" in function): msg = ( "Unsupported function\n\nTo use a JSON schema as a function, " "it must have a top-level 'title' key to be used as the function name." ) raise ValueError(msg) Verification Results Automated Tests I created a reproduction script reproduce_issue.py to confirm the behavior. Before Fix: The script would have raised the generic "Unsupported function" error claiming description was also required. After Fix: The script now confirms that the new, specific error message is raised when title is missing. (Note: Verification was performed by inspecting the code logic and running a lightweight reproduction script locally, as full suite verification had environment dependency issues.) --------- Co-authored-by: Mason Daugherty <github@mdrxy.com>
1 parent d22cfaf commit e261924

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

libs/core/langchain_core/utils/function_calling.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,20 @@ def convert_to_openai_function(
428428
"dict", _convert_python_function_to_openai_function(function)
429429
)
430430
else:
431+
if isinstance(function, dict) and (
432+
"type" in function or "properties" in function
433+
):
434+
msg = (
435+
f"Unsupported function\n\n{function}\n\nTo use a JSON schema as a "
436+
"function, it must have a top-level 'title' key to be used as the "
437+
"function name."
438+
)
439+
raise ValueError(msg)
431440
msg = (
432441
f"Unsupported function\n\n{function}\n\nFunctions must be passed in"
433442
" as Dict, pydantic.BaseModel, or Callable. If they're a dict they must"
434443
" either be in OpenAI function format or valid JSON schema with top-level"
435-
" 'title' and 'description' keys."
444+
" 'title' key."
436445
)
437446
raise ValueError(msg)
438447

libs/core/tests/unit_tests/utils/test_function_calling.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,3 +1180,32 @@ class MyModel(BaseModel):
11801180

11811181
func = convert_to_openai_function(MyModel, strict=True)
11821182
assert func["parameters"]["additionalProperties"] is False
1183+
1184+
1185+
def test_convert_to_openai_function_json_schema_missing_title_with_type() -> None:
1186+
"""Test error for JSON schema with 'type' but no 'title'."""
1187+
schema_without_title = {
1188+
"type": "object",
1189+
"properties": {"arg1": {"type": "string"}},
1190+
}
1191+
with pytest.raises(ValueError, match="must have a top-level 'title' key"):
1192+
convert_to_openai_function(schema_without_title)
1193+
1194+
1195+
def test_convert_to_openai_function_json_schema_missing_title_properties() -> None:
1196+
"""Test error for JSON schema with 'properties' but no 'title'."""
1197+
schema_without_title = {
1198+
"properties": {"arg1": {"type": "string"}},
1199+
}
1200+
with pytest.raises(ValueError, match="must have a top-level 'title' key"):
1201+
convert_to_openai_function(schema_without_title)
1202+
1203+
1204+
def test_convert_to_openai_function_json_schema_missing_title_includes_schema() -> None:
1205+
"""Test that the error message includes the schema for debugging."""
1206+
schema_without_title = {
1207+
"type": "object",
1208+
"properties": {"my_field": {"type": "integer"}},
1209+
}
1210+
with pytest.raises(ValueError, match="my_field"):
1211+
convert_to_openai_function(schema_without_title)

0 commit comments

Comments
 (0)