When a tool declares credentials that aren't stored on the server, the worker task ends up as FAILED (retryable) instead of FAILED_WITH_TERMINAL_ERROR. Conductor then retries it pointlessly up to retry_count times.
Missing credentials are a config error — retrying won't fix them. The exception handler in _dispatch.py only marks TerminalToolError as terminal; a plain RuntimeError from a missing credential falls through to the retryable FAILED branch.
Repro: run test_suite2 test_credential_lifecycle with no credentials stored — paid_tool_a gets status FAILED instead of COMPLETED_WITH_ERRORS.
When a tool declares credentials that aren't stored on the server, the worker task ends up as FAILED (retryable) instead of FAILED_WITH_TERMINAL_ERROR. Conductor then retries it pointlessly up to retry_count times.
Missing credentials are a config error — retrying won't fix them. The exception handler in _dispatch.py only marks TerminalToolError as terminal; a plain RuntimeError from a missing credential falls through to the retryable FAILED branch.
Repro: run test_suite2 test_credential_lifecycle with no credentials stored — paid_tool_a gets status FAILED instead of COMPLETED_WITH_ERRORS.