Skip to content

fix(app): sign multimodal tool file URL in MessageFile record#39244

Open
sergioperezcheco wants to merge 2 commits into
langgenius:mainfrom
sergioperezcheco:fix/sign-multimodal-tool-file-url
Open

fix(app): sign multimodal tool file URL in MessageFile record#39244
sergioperezcheco wants to merge 2 commits into
langgenius:mainfrom
sergioperezcheco:fix/sign-multimodal-tool-file-url

Conversation

@sergioperezcheco

Copy link
Copy Markdown
Contributor

When an LLM returns image content (URL or base64), _handle_multimodal_image_content in base_app_runner.py stored an unsigned relative URL (/files/tools/) in the MessageFile record. The /files/tools/. endpoint validates timestamp, nonce, and sign query parameters via ToolFileQuery, so accessing these stored URLs fails with a 400 pydantic ValidationError (all three fields reported as missing).

This builds the URL through sign_tool_file(), the same helper ToolFileMessageTransformer already uses for its tool file links, so the stored MessageFile URL carries the required signature. The file extension is now resolved once after the file is saved (covering both the URL-fetch and base64 branches) via resolve_extension(filename, mimetype) instead of only being computed inside the base64 branch.

Added a regression assertion in test_handle_multimodal_image_content_with_url that the stored URL contains timestamp/nonce/sign and the tool file id. The existing multimodal test suite (7 tests) and base_app_runner tests (18 tests) pass, and ruff lint/format are clean.

This is the base_app_runner.py location called out in #39222; it complements #39225, which signs the ToolFileMessageTransformer.get_tool_file_url path.

Fixes #39222

_handle_multimodal_image_content stored an unsigned relative URL
(/files/tools/<id>) in the MessageFile record. The /files/tools/<id>
endpoint (controllers/files/tool_files.py) validates timestamp, nonce,
and sign query params via ToolFileQuery, so these URLs 400 on access.

Build the URL with sign_tool_file(), matching how ToolFileMessageTransformer
already signs tool file links. The extension is now resolved once for both
the URL-fetch and base64 branches via resolve_extension().

Signed-off-by: sergioperezcheco <checo520@outlook.com>
@sergioperezcheco

Copy link
Copy Markdown
Contributor Author

Heads up — every CI job on this PR timed out at the 10m0s mark, and the Validate PR title check failed with a transient GitHub 503 (the amannn/action-semantic-pull-request action hit No server is currently available to service your request), which then cascaded the rest into skipping. The unit tests covering this change (test_base_app_runner_multimodal.py) pass locally, so this looks like a runner/infra issue rather than a code problem. Would one of you mind re-running the failed jobs when the queue frees up?

Previous run failed across all jobs with 'self-hosted runner lost communication with the server'. No code changes.
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jul 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 54.01% 54.01% 0.00%
Strict coverage 53.50% 53.50% 0.00%
Typed symbols 34,407 34,407 0
Untyped symbols 29,577 29,577 0
Modules 3029 3029 0

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

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool file URLs generated without signature parameters causing 400 validation errors

1 participant