Skip to content

Agents cannot create PRs — gh CLI not installed in container, curl not in shell whitelist #65

Description

@HappyLiang12

Problem

Even when an agent successfully pushes a branch to GitHub, it cannot create a pull request. Two independent blockers prevent PR creation:

  1. gh CLI is not installed in the backend container image — gh pr create fails with "command not found"
  2. curl is not in the TOOLS_SHELL_WHITELIST — agents cannot call the GitHub API via shell_exec to create PRs as a fallback

Impact

The git pack workflow is incomplete: agents can clone, edit, commit, and push (with workaround for #60), but cannot complete the final step of creating a PR. The agent ends up asking the human to manually create the PR, defeating the purpose of the autonomous git workflow.

Background & Context

The governed plugin/tool-pack system (PR #21) introduced a git_create_pr tool that wraps gh pr create. The tool is seeded in V33 migration, approved, and granted to the dev role. However, the underlying gh CLI binary was never installed in the backend Docker image's runtime stage.

Additionally, the shell_exec handler restricts commands to a whitelist (git,ls,cat,find,echo,mvn,npm,pnpm by default), which excludes curl. When gh fails, the agent has no way to call the GitHub REST API to create a PR programmatically.

Reproduction

Prerequisites

  • Aria Conductor running on latest main (commit 63176d0)
  • MariaDB, backend, ADK, and frontend containers all healthy
  • LLM provider configured (tested with qwen3.7-max via mlop-llm-gateway-dev)
  • GITHUB_TOKEN stored in pack credential store

Step 1: Store GITHUB_TOKEN

curl -X POST http://localhost:8080/api/v1/packs/pack-git-0001/credentials \
  -H "Content-Type: application/json" \
  -d '{"key": "GITHUB_TOKEN", "value": "ghp_..."}'

Step 2: Create a dev agent with git pack tools

curl -X POST http://localhost:8080/api/v1/agents \
  -H "Content-Type: application/json" \
  -d '{"name": "DevAgent", "role": "dev", "agentType": "NATIVE"}'

Note: Due to issue #62, the agent will be auto-assigned weak-model-safe harness profile which denies shell_exec. Override it manually:

UPDATE agents SET config='{"harnessProfile":"default"}' WHERE id='<agent-id>';

Then restart the backend.

Step 3: Start a run that includes PR creation

curl -X POST http://localhost:8080/api/v1/runs \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "<agent-id>",
    "promptSeed": "Clone https://github.com/HappyLiang12/aria-conductor.git, create a branch, delete AriaPage.tsx, commit, push, and create a PR"
  }'

Step 4: Approve all shell_exec and git_push approval gates as they appear

Monitor GET /api/v1/approvals for PENDING items and approve them.

Step 5: Observe failures

gh CLI attempt:

shell_exec: gh pr create --title "..." --body "..."
Output: sh: gh: command not found

curl fallback attempt:

shell_exec: curl -s -X POST -H "Authorization: token ..." https://api.github.com/repos/.../pulls
Output: Error: Shell execution is disabled. Allowed commands: git,ls,cat,find,echo,mvn,npm,pnpm

http_request tool attempt:
The http_request tool only supports GET/POST with URL — it does not support request bodies, custom auth headers, or the JSON payload needed for the GitHub PR creation API.

E2E Evidence

From run 08c4ff38-46ea-414b-85b1-31b84d7fc262 (2026-07-29):

The agent completed steps 1-9 successfully (clone, set remote URL, checkout branch, delete file, verify no references, git add, git config, git commit, git push) but could not create the PR. The agent's final output:

PR Creation — Manual Step Required
The gh CLI is not installed in this environment and shell_exec restricts commands to git/ls/cat/find/echo/mvn/npm/pnpm, so curl cannot be used to call the GitHub API. The http_request tool doesn't support request bodies or custom auth headers.

The branch was successfully pushed to fix/remove-dead-aria-page-v2 (verified via git ls-remote), but the PR had to be created manually.

Dockerfile Analysis

The backend Dockerfile (agent-control-tower/Dockerfile) installs git in the build stage but does not install gh in either the build or runtime stage:

# Build stage — has git but no gh
FROM maven:3.9-eclipse-temurin-21 AS build
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

# Runtime stage — no git, no gh
FROM eclipse-temurin:21-jre-jammy AS runtime
# ... only JRE, no CLI tools

The runtime stage is a minimal JRE image with no git, no gh, and no curl.

Suggested Fixes

Option A: Install gh CLI in the Dockerfile (recommended)

Add gh to the backend runtime stage in agent-control-tower/Dockerfile:

RUN apt-get update \
    && apt-get install -y curl \
    && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list \
    && apt-get update \
    && apt-get install -y gh \
    && rm -rf /var/lib/apt/lists/*

This lets gh pr create work natively since GH_TOKEN is already injected into the process environment by GitPackHandler.

Option B: Add curl to the shell whitelist

Add curl to the default TOOLS_SHELL_WHITELIST so agents can call external APIs via shell_exec.

Option C: Extend http_request to support request bodies and custom headers

Add body and headers parameters to the http_request tool schema so agents can call REST APIs directly.

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions