Files
composiohq__composio/python/tests/test_custom_tools.py
Alberto Schiabel 53c024a9c8 fix(py): keep local results when remote multi-execute transport fails (#4386)
## Summary

Follow-up to #4310. The TypeScript SDK (since #3800) catches a thrown
backend call for the remote half of a mixed
`COMPOSIO_MULTI_EXECUTE_TOOL` batch and turns it into one failure entry
per remote slug, so completed local results are not lost. The Python SDK
still let the exception escape `_route_multi_execute`, discarding every
local result that had already run.

This ports the TypeScript behavior so both SDKs return the same shape on
a remote transport failure.

Fixes #

## Changes

- Catch the remote future's exception in `_route_multi_execute` and keep
`str(error)`, falling back to `Remote tool execution failed` when the
message is empty (same fallback as TS).
- Synthesize `{response: {successful: False, data: {}, error},
tool_slug, error}` for each remote index and merge them in original
request order.
- Recompute `total_count` / `success_count` / `error_count` on transport
failure, as TS does.
- Add two regression tests mirroring the TS cases in
`customToolRouting.test.ts`: local results preserved with per-tool
remote errors, and the empty-message fallback.

## Type of change

- [x] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change

## How Has This Been Tested?

- `uv run --locked --group dev pytest tests/test_custom_tools.py -q`: 87
passed.
- `uv run --locked --group dev nox -s chk`: ruff and mypy clean.
- Without the source change, the new
`test_remote_transport_failure_keeps_local_results` raises
`RuntimeError: remote unavailable` out of `_route_multi_execute`.

## Checklist

- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [ ] I updated documentation as needed
- [x] I added tests or explain why not applicable
- [ ] I added a changeset if this change affects published packages
(Python does not use Changesets)

## Additional context

TypeScript reference:
`ts/packages/core/src/models/ToolRouterSession.ts`, the
`remoteErrorMessage` branch, and the test "should preserve successful
local results when remote transport fails".

https://claude.ai/code/session_01PAXMbiZd3qPoJ8Z9uPvEAb
EOF -R ComposioHQ/composio
2026-09-08 18:11:25 +02:00

53 KiB