python: remove implicit PATH fallback for CLI executable resolution by SteveSandersonMS · Pull Request #2528 · github/copilot-sdk · GitHub
Skip to content

python: remove implicit PATH fallback for CLI executable resolution - #2528

Draft
SteveSandersonMS wants to merge 1 commit into
mainfrom
copilot/2524-python-no-path-fallback
Draft

python: remove implicit PATH fallback for CLI executable resolution#2528
SteveSandersonMS wants to merge 1 commit into
mainfrom
copilot/2524-python-no-path-fallback

Conversation

@SteveSandersonMS

Copy link
Copy Markdown
Contributor

Summary

Part of #2524 (Consolidate runtime discovery, acquisition, and embedding). Removes the Python SDK's implicit fallback to PATH-based executable resolution, satisfying the required outcome:

Python does not implicitly select an executable through PATH; it uses the SDK-managed runtime or an explicitly configured path.

Background

Commit 05dd60e (#793) added a shutil.which(cli_path) fallback in CopilotClient._start_cli_server that runs whenever the resolved cli_path does not exist as a file. This let the SDK silently pick up an arbitrary same-named executable from the host PATH instead of using the runtime the SDK actually resolved (explicit path > COPILOT_CLI_PATH > SDK-managed download, see _resolve_runtime_entrypoint). #1934 flagged this explicitly for removal, and #2522/#2524 carry that forward.

I confirmed on latest main (0921029) and on the in-flight roji-unify-runtime-artifacts branch (#2505) that this fallback is unchanged in both — #2505 only changes how the runtime is downloaded/verified from GitHub Releases for Python/.NET/Go/Java, not this PATH-search behavior at process start, so this is not duplicating that work.

What changed

  • python/copilot/client.py: _start_cli_server now raises a clear RuntimeError when the resolved cli_path doesn't exist, instead of falling back to shutil.which. Removed the now-unused shutil import.
  • python/test_client.py: added a regression test that plants a same-named decoy executable on PATH and asserts it is never used when the configured path is missing.

Not in scope here (tracked separately on #2524)

Validation

  • ruff check / ruff format --check on changed files: pass.
  • ty check on copilot/client.py: pass.
  • pytest python/test_client.py python/test_cli_download.py: same 79 pre-existing environment-only failures as unmodified main (fake local CLI binary used for offline testing has no real e2e semantics); all path-resolution tests, including the new regression test, pass with zero new failures.

Closes #2524 once merged (remaining #2524 items tracked in the follow-up comment on that issue).

The runtime start path fell back to shutil.which(cli_path) whenever the
resolved cli_path did not exist as a file. This let the SDK implicitly
select an arbitrary same-named executable found on the host PATH instead
of failing when the SDK-managed runtime or an explicitly configured path
was not actually present, re-introducing the PATH-search behavior
originally added by 05dd60e that #2524 asks to remove.

Resolution order is unchanged (explicit path > COPILOT_CLI_PATH >
SDK-managed downloaded runtime, see _resolve_runtime_entrypoint); only the
undocumented PATH-search fallback at process start is removed. A missing
resolved path now raises a RuntimeError up front instead of silently
searching PATH.

Adds a regression test asserting that a same-named executable placed on
PATH is not used when the configured path does not exist.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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

Labels

sdk/python sdk-v2 Work planned for Copilot SDK v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2] Consolidate runtime discovery, acquisition, and embedding

1 participant