Skip to content

fix(agent): don't crash the error mapper on LLM Gateway raw vendor error details - #1137

Open
ionut-mihalache-uipath wants to merge 1 commit into
mainfrom
fix/jev-gateway-errors
Open

ionut-mihalache-uipath wants to merge 1 commit into
mainfrom
fix/jev-gateway-errors

Conversation

@ionut-mihalache-uipath

@ionut-mihalache-uipath ionut-mihalache-uipath commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What

  • agent/exceptions/llm.py: _classify no longer crashes on object details. LLM Gateway raw vendor passthrough errors carry an object detail, {"error_type": ..., "message": ...}, not a ProblemDetails string. _classify used to pass that object through as the AgentRuntimeError detail, so UiPathErrorContract failed validation (detail: Input should be a valid string). The run then ended with a generic "An unexpected error occurred". Now only a string detail (the gateway's own ProblemDetails text) is ever displayed. Any other detail is dropped, and the mapper's own detail is used: the canned text for 400, the HTTP reason phrase otherwise. The vendor's message is deliberately not shown: it is relayed provider text and may carry customer PII, the same rule the 400 branch already follows. It stays on the LLM call span.
  • jev_classifier_tool.py: the gateway's unknown-model error is recognised. The gateway answers an unserved model with 400 "Unsupported model used. The list of supported models is : ...". The tool now treats this like TypeSafe's "Unknown model: ...", so it surfaces as Unknown Jev model (LLM_PROVIDER_BAD_REQUEST, a user error). The vendor text is used only to recognise the error. The message shown is the tool's own fixed text, naming the configured model and the tool.
  • Versions. uipath-langchain is bumped to 0.18.31. The floors rise to uipath>=2.14.36 (fix(agent): require the jev classifier model instead of defaulting to jev-latest uipath-python#1930) and to uipath-llm-client>=1.21.1 / uipath-langchain-client[...]>=1.21.1 (fix: require model_name in UiPathJevClient instead of defaulting to jev-latest uipath-llm-client-python#148). Those releases drop the unserved jev-latest default and make the Jev model required. uv.lock is regenerated against PyPI.

How it was found

I ran a low-code agent with the Jev tool on alpha through the local runtime. With the old jev-latest default, the call to agenthub_/llm/raw/vendor/typesafe/model/jev-latest/completions returned a 400, and the error mapper crashed on its object detail. With this change, an unserved model (jev-9.9.9) fails cleanly:

Unknown Jev model: Jev has no model named 'jev-9.9.9'. Choose another model in the settings of tool 'Jev Classifier'.

With jev-1.13.0, the call returns 200 and the agent completes.

Testing

  • pytest: the full suite passes against the released uipath 2.14.36 and uipath-llm-client 1.21.1 from PyPI. New tests:
    • A 400 with an object detail gets the canned detail.
    • For a 400 and a 500, the relayed vendor message never appears in the error's detail, str() or repr().
    • The gateway's unsupported-model 400 maps to "Unknown Jev model".
  • ruff check, ruff format --check, scripts/lint_httpx_client.py, mypy --config-file pyproject.toml . and uv lock --check are all clean.
  • uv.lock also changes markers on a few transitive packages (black, culsans, httpcore2, aiologic). That is the resolver's output for the new versions: an unmodified main locks with no changes under the same uv.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XpbvUoddLSo7W61dwpjKFC

Copilot AI balanced review requested due to automatic review settings October 7, 2026 15:27

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.

🟡 Changes recommended

The generic mapper now exposes potentially sensitive raw vendor messages to users.

1 open finding
What changed in this PR

Improves LLM Gateway error handling and Jev unknown-model classification.

Changes:

  • Handles object-shaped gateway error details.
  • Recognizes Gateway unsupported-model responses.
  • Updates package versions, dependencies, lockfile, and tests.
File Description
src/​uipath_langchain/​agent/​exceptions/​llm.py Extracts messages from object details.
src/​uipath_langchain/​agent/​tools/​internal_tools/​jev_classifier_tool.py Classifies unsupported models.
tests/​agent/​test_llm.py Tests object-detail handling.
tests/​agent/​tools/​internal_tools/​test_jev_classifier_tool.py Tests Gateway unknown-model responses.
pyproject.toml Bumps package and dependency versions.
uv.lock Regenerates locked dependencies.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/uipath_langchain/agent/exceptions/llm.py Outdated

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.

🟡 Changes recommended

The PR description contradicts the implemented PII-safe masking behavior, and one new test lacks required annotations.

2 open findings
1 resolved since last review

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment on lines +207 to +211
# Only the gateway's own ProblemDetails string is first-party text. A raw
# vendor passthrough error carries an object detail relaying the vendor's
# message, which may hold customer PII: never display it.
if not isinstance(gateway_detail, str):
gateway_detail = None
Comment thread tests/agent/test_llm.py Outdated
…ror details

LLM Gateway raw vendor passthrough errors carry an object detail
({"error_type", "message"}), not a ProblemDetails string. _classify passed
it through as the AgentRuntimeError detail, so UiPathErrorContract failed
validation and the run ended with a generic "unexpected error". Only the
gateway's own string detail is first-party text; an object detail relays the
vendor's message, which may carry customer PII, so it is dropped and the
mapper's own detail is used (the canned text for 400, the reason phrase
otherwise).

The Jev tool recognises the gateway's "Unsupported model used" 400 as an
unknown model, so a model the gateway does not serve surfaces as "Unknown Jev
model" (user error, with the tool's own message) instead of a generic
provider error.

Bumps uipath-langchain to 0.18.31 and the floors to uipath>=2.14.36 and
uipath-llm-client / uipath-langchain-client>=1.21.1, which drop the
unserved jev-latest default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpbvUoddLSo7W61dwpjKFC
@ionut-mihalache-uipath ionut-mihalache-uipath changed the title fix(agent): surface LLM Gateway raw vendor errors instead of crashing the error mapper fix(agent): don't crash the error mapper on LLM Gateway raw vendor error details Oct 8, 2026
@sonarqubecloud

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
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.

2 participants