Skip to content

fix: tolerate malformed tool output schemas at agent startup [PC-4546]#983

Open
UiPathPetruPopa wants to merge 8 commits into
mainfrom
fix/tool-output-schema-non-blocking
Open

fix: tolerate malformed tool output schemas at agent startup [PC-4546]#983
UiPathPetruPopa wants to merge 8 commits into
mainfrom
fix/tool-output-schema-non-blocking

Conversation

@UiPathPetruPopa

Copy link
Copy Markdown

Agents that ran on the legacy Temporal/.NET runtime crash on URT at startup with
AGENT_STARTUP.INVALID_TOOL_CONFIG when a tool's output schema has a dangling
$ref (e.g. a .NET decimal?Nullableofdecimal with no $defs). URT eagerly
converts every tool schema to Pydantic and throws; the old runtime never resolved
$refs. Output schemas are design-time only (guardrails + eval sims), never used
during execution, so the crash is gratuitous.

  • Added create_output_model() in jsonschema_pydantic_converter.py — falls back
    to an empty model (with a warning) instead of raising on an unparseable schema.
  • Applied it to the 5 output-schema tool factories: process, escalation,
    integration, analyze_files, deeprag.
  • Left fatal (intentional): all input schemas and the agent-level output schema
    in react/utils.py (used at runtime for terminate-node validation).

Copilot AI review requested due to automatic review settings July 13, 2026 08:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents agent startup failures on URT when a tool’s output JSON schema is malformed (e.g., dangling $ref from legacy Temporal/.NET runtime exports). Since tool output schemas are design-time only, the new behavior degrades output typing to an empty model with a warning instead of raising AGENT_STARTUP.INVALID_TOOL_CONFIG.

Changes:

  • Added create_output_model() to convert tool output schemas non-fatally, falling back to an empty schema and logging a warning.
  • Updated the 5 tool factories that convert output schemas (process, escalation, integration, analyze_files, deeprag) to use create_output_model().
  • Added coverage ensuring malformed output schemas don’t block tool creation; bumped package version to 0.14.6.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/uipath_langchain/agent/react/jsonschema_pydantic_converter.py Adds non-fatal output-schema conversion with a safe empty-model fallback and warning logging.
src/uipath_langchain/agent/tools/process_tool.py Uses create_output_model() for process tool output schema conversion.
src/uipath_langchain/agent/tools/escalation_tool.py Uses create_output_model() for escalation channel output schema conversion.
src/uipath_langchain/agent/tools/integration_tool.py Uses create_output_model() for integration tool output schema conversion (when present).
src/uipath_langchain/agent/tools/internal_tools/analyze_files_tool.py Uses create_output_model() for internal analyze-files output schema conversion.
src/uipath_langchain/agent/tools/internal_tools/deeprag_tool.py Uses create_output_model() for DeepRAG output schema conversion.
tests/agent/tools/test_tool_factory.py Adds a regression test ensuring malformed output schemas are non-blocking across the 5 affected tool factories.
pyproject.toml Bumps project version to 0.14.6.
uv.lock Updates locked version to 0.14.6.

Comment thread tests/agent/tools/test_tool_factory.py Outdated

@andreitava-uip andreitava-uip left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to think of a different fallback, Ideally only remove the malformed parts and keep the rest of the fields?

Comment thread src/uipath_langchain/agent/react/jsonschema_pydantic_converter.py Outdated
@UiPathPetruPopa UiPathPetruPopa force-pushed the fix/tool-output-schema-non-blocking branch from 513cc17 to 871a960 Compare July 13, 2026 15:53
Comment on lines +165 to +175
except AgentStartupError as e:
# Last-resort net for a non-$ref failure we didn't neutralize. Intentionally
# narrow (AgentStartupError only): other errors are unexpected and should
# surface rather than be silently swallowed.
logger.warning(
"Tool %r output schema still unparseable after neutralizing dangling "
"refs; falling back to an empty model (non-blocking): %s",
tool_name,
e.error_info.detail,
)
return create_model(_EMPTY_OUTPUT_SCHEMA)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove this last resort fallback. The dangling refs fix is good because it (mostly) preserves functionality such as file attachments and guardrails.

For more fatal issues, I'd rather throw up-front than run into obscure silent bugs at runtime.

Most malformed issues we discovered were such dangling refs. Until further notice I wouldn't add extra fallbacks.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed last resort fallback.

@sonarqubecloud

Copy link
Copy Markdown

title="Invalid schema",
detail=(
f"Type '{type_name}' could not be resolved. "
f"Check that all $ref targets have matching entries in $defs."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is this message applicable here since this case is treated in the create_output_model method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants