fix(frontend): stop frontend bash probes on cloud runtimes#761
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
all-hands-bot
left a comment
There was a problem hiding this comment.
Taste Rating: 🟢 Good taste — Clean, targeted fix for a real privacy/security issue.
VERDICT: ✅ Worth merging
KEY INSIGHT: The fix correctly gates local filesystem probes to prevent leaking host paths to cloud runtimes while preserving the existing fallback chain in consumers (conversation metadata → local git info → undefined).
[RISK ASSESSMENT]
- [Overall PR] Risk Assessment: 🟢 LOW
This is a surgical bug fix that prevents leaking local filesystem paths to cloud runtimes. Changes are minimal (just adding backend kind gates), well-tested, and cause no breaking changes. Cloud backends already rely on conversation metadata as the source of truth; local behavior is unchanged. Consumer code (git-control-bar.tsx) already handles the fallback chain correctly.
Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
Workflow run: https://github.com/OpenHands/agent-canvas/actions/runs/26438260977
📸 Snapshot Test Report✅ All snapshots match the main branch baselines.
✅ Unchanged snapshots (73)
Generated by the Snapshot Tests workflow. This comment was created by an AI agent (OpenHands) on behalf of the repo maintainers. |
Why
Description
When a user is connected to a Cloud backend (e.g. OpenHands Cloud production) and creates a new conversation, the frontend immediately fires
/api/bash/execute_bash_commandon the cloud runtime to probe git metadata. Thecwdin that request is a local filesystem path read fromlocalStorage(e.g./Users/<user>/.openhands/agent-canvas/workspaces), which leaks the host filesystem layout to the cloud runtime and resolves to nothing meaningful there.Steps to reproduce
npm run devinagent-canvas.<BackendSelector />and click Add Backend.Expected behavior
/api/bash/execute_bash_commandis not driven by the frontend on cloud backends. Cloud uses conversation metadata (selected_repository,git_provider,selected_branch) as the source of truth for the chat's git control bar.Root cause
useLocalGitInfo(src/hooks/query/use-local-git-info.ts) anduseHasGitCommits(src/hooks/query/use-has-git-commits.ts) had no backend-kind gate on theirenabledpredicate. On cloud,AgentServerRuntimeService.executeCommandroutes throughcallCloudProxyto/api/bash/execute_bash_command.useLocalGitInfoadditionally falls back togetAgentServerWorkingDir()(local config) when the conversation'sworkspace.working_diris missing — that's the leak path.Fix
Gate both hooks on
backend.kind === "local".useWorkspaceFilesis intentionally left untouched (it powers the Files tab's file-list sub-view; needs a cloud-native replacement endpoint as a follow-up).Acceptance criteria
/api/bash/execute_bash_commandrequests are issued from the frontend when the active backend is cloud.git remote get-url origin/git rev-parse --abbrev-ref HEAD/git rev-parse --verify HEADas before.Summary
useLocalGitInfoanduseHasGitCommitsonbackend.kind === "local"so the frontend no longer drives/api/bash/execute_bash_commandon cloud runtimes.getAgentServerWorkingDir()localStorage) was sent ascwdto a cloud sandbox.selected_repository,git_provider,selected_branch) — no UX regression in the chat's git control bar.useWorkspaceFilesis intentionally not gated; it powers the Files tab's file-list sub-view and there is no cloud-native replacement endpoint yet. Tracked as a follow-up.Root cause
AgentServerRuntimeService.executeCommandis cloud-aware: on cloud it routes throughcallCloudProxyto/api/bash/execute_bash_command. The two probe hooks called this service with no backend gate, so they fired on cloud immediately after a new conversation was created.useLocalGitInfomade it worse by falling back togetAgentServerWorkingDir()(a local-machine path read from localStorage) when the cloud conversation hadn't yet populatedworkspace.working_dir, leaking that host path to the remote runtime.Changes
src/hooks/query/use-local-git-info.tsuseActiveBackend, deriveisLocalBackend, and AND it into theenabledpredicate.src/hooks/query/use-has-git-commits.tshasCommitsstaysnulland the Files tab keeps its optimistic diff-view default — fine in practice since cloud conversations almost always have an attached repo with commits.__tests__/hooks/query/use-local-git-info.test.tsx(new)executeCommandnot called (regression test).executeCommandcalled with the expected git probe and parsed result.__tests__/hooks/query/use-has-git-commits.test.tsx(new)executeCommandnot called;hasCommitsisnull.executeCommandcalled forgit rev-parse --verify HEAD;hasCommitsresolves totrue.Issue Number
Resolves #760
How to Test
npm run devinagent-canvas.<BackendSelector />and click Add Backend.Type
🐳 Docker images for this PR
• GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas
ghcr.io/openhands/agent-canvasghcr.io/openhands/agent-server:1.23.0-pythonopenhands-automation==1.0.0a36a8534cade7c585de432bfff711ad02ef038ddacPull (multi-arch manifest)
# Multi-arch manifest — Docker automatically pulls the correct architecture docker pull ghcr.io/openhands/agent-canvas:sha-6a8534cRun
All tags pushed for this build
About Multi-Architecture Support
sha-6a8534c) is a multi-arch manifest supporting both amd64 and arm64sha-6a8534c-amd64) are also available if needed