Skip to content

Fix missing target-repo in config.json for cross-repo create_pull_request#19284

Merged
pelikhan merged 2 commits into
mainfrom
copilot/fix-missing-target-repo-config
Mar 3, 2026
Merged

Fix missing target-repo in config.json for cross-repo create_pull_request#19284
pelikhan merged 2 commits into
mainfrom
copilot/fix-missing-target-repo-config

Conversation

Copilot AI commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

config.json (consumed by the MCP server during the agent job) was missing target-repo and all other cross-repo fields for create_pull_request. The conclusion job's GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG had the full config correctly; only the agent-side config was broken. This caused the MCP server to fall back to GITHUB_REPOSITORY as the target, making cross-repo PRs impossible — the agent would either create the PR in the wrong repo or get rejected for passing the owning repo explicitly.

Changes

  • safe_outputs_config_generation_helpers.go — Refactored generatePullRequestConfig() to accept *CreatePullRequestsConfig (full struct) and emit target-repo, allowed_repos, base_branch, draft, reviewers, title_prefix, and fallback_as_issue. Now uses generateTargetConfigWithRepos() as its base, consistent with close_issue.

  • safe_outputs_config_generation.go — Updated call site to pass the full config struct.

  • safe_outputs_tools.json — Fixed misleading repo parameter description: omitting repo defaults to the configured target-repo, not the workspace root.

  • safe_outputs_tools_loader.cjs — When config.create_pull_request["target-repo"] is set, appends a contextual note to both the tool description and repo parameter description so agents know they can omit repo.

  • safe_outputs_handlers.cjs — When resolveAndValidateRepo fails because the agent passed the owning repo while target-repo is configured differently, appends a targeted hint explaining the mismatch.

  • safe_outputs_config_generation_test.go — Added tests covering cross-repo config generation and backward compatibility (no target-repo still works).

Example: A workflow with target-repo: caido/proxy-frontend now produces:

{"create_pull_request":{"base_branch":"dev","draft":true,"max":1,"reviewers":["corb3nik"],"target-repo":"caido/proxy-frontend","title_prefix":"[refactor] "}}

instead of:

{"create_pull_request":{"max":1}}

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw flow (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw k/gh-aw/gh-aw/pk-c (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha se 6087974/b108/vet.cfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha /tmp/gh-aw-test-runs/20260303-002201-41658/test-3264140609 rev-parse /usr/bin/git "prettier" --wrigit git /sh git remo�� add origin /usr/bin/git ath ../../../.prgit ../../../**/*.jsrev-parse 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /usr/bin/git --git-dir go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --git-dir go /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha SameOutput35423236/001/stability-test.md GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go ortc�� -json stmain.go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu--jq (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /usr/bin/sh GOINSECURE GOMOD GOMODCACHE sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel node /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel node /usr/bin/git /tmp/TestHashCongit sh /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel owner /usr/bin/git 0 -j ACCEPT git rev-�� --show-toplevel go /opt/hostedtoolcache/node/24.13.1/x64/bin/node b/workflows sh 64/bin/go node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env y.md GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -bool -buildtags /usr/bin/git -errorsas -ifaceassert -nilfunc /usr/bin/git remo�� -v -tests /usr/sbin/iptables -json GO111MODULE 64/bin/go iptables (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha 6087974/b424/_pkg_.a go 6087974/b424=> ck '**/*.cjs' '*git GO111MODULE 64/bin/go git rev-�� CxFj/4N_hV3O2Cg4KalLpCxFj go /opt/hostedtoolcache/node/24.13.1/x64/bin/node -json GO111MODULE 64/bin/go node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha /usr/bin/git bash /usr/bin/git --noprofile git 64/bin/go git rev-�� --show-toplevel node /usr/bin/git --write **/*.cjs 64/bin/go git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ck 'scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha 35126d5394e2a1caGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD erignore ache/go/1.25.0/xGO111MODULE env 8008084/b412/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE b/gh-aw/pkg/test-o GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD erignore go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha /tmp/go-build3746087974/b416/sliceutil.test (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -bool -buildtags /usr/bin/git -errorsas -ifaceassert -nilfunc git -C /tmp/compile-all-instructions-test-1033509952/.github/workflows config /usr/bin/git remote.origin.urgit **/*.cjs 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --git-dir go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha t0 go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -x c /usr/bin/git - git 64/bin/go git rev-�� --show-toplevel node /usr/bin/git --write **/*.cjs 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel go /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel node /usr/bin/git /home/REDACTED/worgit resolved$ /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha agent-persona-explorer.md GO111MODULE /opt/hostedtoolcache/go/1.25.0/x/tmp/gh-aw-git-clone-2021025306 GOINSECURE GOMOD GOMODCACHE go env r/test-repo/actions/secrets GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE erignore env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --show-toplevel sh /usr/bin/git "prettier" --chegit l /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel node /usr/bin/git git (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha h ../../../.pret.prettierignore .cfg sh user.name (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go estl�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE 1/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/sh GOINSECURE GOMOD GOMODCACHE 9D/TE8z8DiNDUNGW-4fRZ3A/6PNtGrvPdB_1y-ee1BPv env '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE 6ffdf860dfc35a80e1ae4f9aff292fb98724de9877836669-d GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/node GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 1/x64/bin/node GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE Xe/zd3aBy0104K8ZfExHKi7/u8U4vpCVJ6IIRF6zALNG (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE bin/sh GOINSECURE GOMOD GOMODCACHE go env '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE de/node/bin/sh GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE h GOINSECURE GOMOD GOMODCACHE go env '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go m/_n�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb --jq .object.sha h ../../../.pret.prettierignore .cfg 64/pkg/tool/linux_amd64/vet user.email (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1430263850/.github/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha h ../../../.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel go /usr/bin/git .js' --ignore-pagit GO111MODULE ser.test git 1/x6�� --show-toplevel ser.test /usr/bin/git -json GO111MODULE k/gh-aw/gh-aw/no--show-toplevel git (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha --local user.email 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel go 64/bin/node .js' --ignore-pagit GO111MODULE 64/pkg/tool/linu--show-toplevel git 1/x6�� --show-toplevel 64/pkg/tool/linu3 /usr/bin/git -json GO111MODULE k/node_modules/.--show-toplevel git (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE uC/HOMpbcQyfh4G56Kcj8To/9s4TpGNoremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE go env */*.ts' '**/*.json' --ignore-path ../../../.prettierignore GO111MODULE 64/pkg/tool/linux_amd64/asm GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/asm (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE erignore env ript formatting GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE ; \ fi (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE erignore env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go **/*.ts **/*.json --ignore-path node /hom�� --write scripts/**/*.js 64/bin/go .prettierignore --log-level=erro/opt/hostedtoolcache/node/24.13.1/x64/bin/npx /usr/bin/git golangci-lint (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build3746087974/b383/cli.test /tmp/go-build3746087974/b383/cli.test -test.testlogfile=/tmp/go-build3746087974/b383/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go ache�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /tmp/go-build1564067028/b383/cli.test /tmp/go-build1564067028/b383/cli.test -test.testlogfile=/tmp/go-build1564067028/b383/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true xterm-color x_amd64/vet /usr/bin/git sh -c "prettier" --wriGOINSECURE git 64/bin/go --show-toplevel go /usr/bin/git sh (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ck 'scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name npx prettier --wGOINSECURE git 64/bin/go --show-toplevel x_amd64/compile /usr/bin/git node /hom�� --write scripts/**/*.js 64/bin/go .prettierignore --log-level=erro/home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/.bin/prettier /usr/bin/git node (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>config.json missing target-repo for create_pull_request in cross-repo workflows</issue_title>
<issue_description>### Summary

When a workflow runs in repo A but configures safe-outputs.create-pull-request.target-repo to repo B, the target-repo value is correctly compiled into GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG (used by the conclusion job) but is missing from the config.json file (used by the MCP server during the agent job). This causes the MCP server to default to GITHUB_REPOSITORY (the owning repo), making cross-repo PRs impossible — the agent cannot target the configured repo.

Reproduction

Workflow file (.github/workflows/proxy-frontend-refactor.md in caido/ai-ops):

---
checkout:
  - repository: caido/proxy-frontend
    path: ./proxy-frontend
    ref: dev
    current: true

safe-outputs:
  create-pull-request:
    target-repo: caido/proxy-frontend
    title-prefix: "[refactor] "
    base-branch: dev
    reviewers: [corb3nik]
    draft: true
---

# Proxy-frontend Refactor

Add a single dummy file to the root of proxy-frontend.

Expected behavior: The MCP server's config.json includes "target-repo":"caido/proxy-frontend". The agent can omit repo and the default resolves to caido/proxy-frontend. Passing repo: "caido/proxy-frontend" explicitly also works.

Actual behavior: The compiled config.json is:

{"create_pull_request":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}

No target-repo, no base_branch, no draft, no reviewers, no title_prefix. The MCP server's getDefaultTargetRepo() falls back to GITHUB_REPOSITORY = caido/ai-ops.

Result: when the agent omits repo, the PR targets caido/ai-ops. When the agent explicitly passes repo: "caido/proxy-frontend", the server rejects it:

Repository 'caido/proxy-frontend' is not in the allowed-repos list. Allowed: caido/ai-ops

Meanwhile, GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG (conclusion job) has the full config:

{"create_pull_request":{"base_branch":"dev","draft":true,"fallback_as_issue":false,"max":1,"max_patch_size":1024,"reviewers":["corb3nik"],"target-repo":"caido/proxy-frontend","title_prefix":"[refactor] "}}

Analysis

There are two separate config generation paths in the compiler, and only one includes target-repo:

Config path 1: config.json (agent job MCP server) — BROKEN

Generated by generateSafeOutputsConfig() in pkg/workflow/safe_outputs_config_generation.go (line 232-240):

if data.SafeOutputs.CreatePullRequests != nil {
    safeOutputsConfig["create_pull_request"] = generatePullRequestConfig(
        data.SafeOutputs.CreatePullRequests.Max,
        1,
        data.SafeOutputs.CreatePullRequests.AllowedLabels,
        data.SafeOutputs.CreatePullRequests.AllowEmpty,
        data.SafeOutputs.CreatePullRequests.AutoMerge,
        data.SafeOutputs.CreatePullRequests.Expires,
    )
}

This calls generatePullRequestConfig() in pkg/workflow/safe_outputs_config_generation_helpers.go (line 135-155), which only passes max, allowed_labels, allow_empty, auto_merge, and expires. It does not pass target-repo, allowed-repos, base_branch, draft, reviewers, title_prefix, or fallback_as_issue.

Config path 2: GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG (conclusion job) — CORRECT

Generated by the handler config builder in pkg/workflow/compiler_safe_outputs_config.go (line 346-368), which uses newHandlerConfigBuilder() and includes all fields:

builder := newHandlerConfigBuilder().
    AddIfNotEmpty("target-repo", c.TargetRepoSlug).
    AddStringSlice("allowed_repos", c.AllowedRepos).
    // ... all other fields

Why close_issue works but create_pull_request doesn't

Compare: close_issue (line 225) uses generateTargetConfigWithRepos() which includes target-repo and allowed_repos. But create_pull_request (line 232) uses generatePullRequestConfig() which does not.

Secondary issue: misleading repo parameter description

In pkg/workflow/js/safe_outputs_tools.json (line 247-249), the repo parameter says:

"If omitted, uses the repository at the workspace root."

This is incorrect. When target-repo is configured, omitting repo defaults to the target-repo value — not the workspace root. The getDefaultTargetRepo() function in actions/setup/js/repo_helpers.cjs (line 101) checks config["target-repo"] first. This misleading description causes agents to explicitly pass repo with the wrong value.

Implementation Plan

1. Fix generatePullRequestConfig() to include target-repo and related fields

File:...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…uest workflows

- Refactor generatePullRequestConfig() to accept full *CreatePullRequestsConfig
  and include target-repo, allowed_repos, base_branch, draft, reviewers,
  title_prefix, and fallback_as_issue in config.json
- Update call site to pass full struct instead of individual fields
- Fix misleading repo parameter description in safe_outputs_tools.json
- Enrich create_pull_request tool description dynamically when target-repo
  is configured in safe_outputs_tools_loader.cjs
- Add helpful hint to error message in safe_outputs_handlers.cjs when
  agent passes owning repo but target-repo is configured differently
- Add tests for target-repo in config.json and backward compatibility

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix missing target-repo in config.json for cross-repo workflows Fix missing target-repo in config.json for cross-repo create_pull_request Mar 3, 2026
@pelikhan pelikhan marked this pull request as ready for review March 3, 2026 00:32
Copilot AI review requested due to automatic review settings March 3, 2026 00:32
@dsyme

dsyme commented Mar 3, 2026

Copy link
Copy Markdown
Collaborator

config.json (consumed by the MCP server during the agent job) was missing target-repo and all other cross-repo fields for create_pull_request. The conclusion job's GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG had the full config correctly; only the agent-side config was broken. This caused the MCP server to fall back to GITHUB_REPOSITORY as the target, making cross-repo PRs impossible — the agent would either create the PR in the wrong repo or get rejected for passing the owning repo explicitly.

THis is strange, as cross repo creation is working for me. Would be good to understand this more

@pelikhan

pelikhan commented Mar 3, 2026

Copy link
Copy Markdown
Collaborator

The safe outputs MCP server probably ignores those fields. The underlying problem here is that we generate the same config twice in 2 code path.

Instead, we should generate config.json in activation once, store it as an artifact and download it in each job.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes cross-repo create_pull_request behavior by ensuring the agent-side MCP config.json includes target-repo and other relevant create-PR configuration fields (matching the already-correct conclusion-job handler config), and improves agent-facing messaging around the optional repo parameter and repo-resolution errors.

Changes:

  • Refactors generatePullRequestConfig() to emit cross-repo fields (target-repo, allowed_repos) plus additional PR settings (e.g., base_branch, draft, reviewers, title_prefix, fallback_as_issue) into agent config.json.
  • Updates tool schema/docs and runtime tool registration/handler error messages to better guide agents in cross-repo scenarios (especially around omitting repo).
  • Updates numerous workflow .lock.yml fixtures to reflect the updated generated config.json and tools schema text.

Reviewed changes

Copilot reviewed 40 out of 40 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/workflow/safe_outputs_config_generation_helpers.go Expands create-PR config generation to include target repo + additional PR fields via generateTargetConfigWithRepos().
pkg/workflow/safe_outputs_config_generation.go Passes full CreatePullRequestsConfig into the refactored generator.
pkg/workflow/safe_outputs_config_generation_test.go Adds tests for cross-repo create-PR config generation + backward compatibility.
pkg/workflow/js/safe_outputs_tools.json Updates create_pull_request tool repo parameter description (agent guidance).
actions/setup/js/safe_outputs_tools_loader.cjs Adds contextual tool/param description enrichment when target-repo is configured.
actions/setup/js/safe_outputs_handlers.cjs Adds a targeted hint when repo validation fails due to owning-repo vs configured target-repo mismatch.
.github/workflows/weekly-safe-outputs-spec-review.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/weekly-editors-health-check.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/unbloat-docs.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/ubuntu-image-analyzer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/tidy.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/test-create-pr-error-handling.lock.yml Refreshes embedded tools descriptions to include updated repo parameter guidance.
.github/workflows/technical-doc-writer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/smoke-project.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/smoke-multi-pr.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/smoke-create-cross-repo-pr.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include cross-repo fields (notably target-repo).
.github/workflows/slide-deck-maintainer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/refiner.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/q.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/poem-bot.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/layout-spec-maintainer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/jsweep.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/instructions-janitor.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/hourly-ci-cleaner.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/go-logger.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/glossary-maintainer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/github-mcp-tools-report.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/functional-pragmatist.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/dictation-prompt.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/developer-docs-consolidator.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/dead-code-remover.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/daily-workflow-updater.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/daily-rendering-scripts-verifier.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/daily-doc-updater.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/daily-doc-healer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/daily-architecture-diagram.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/code-simplifier.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/code-scanning-fixer.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/cloclo.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.
.github/workflows/ci-coach.lock.yml Refreshes embedded safe-outputs config.json/tools descriptions to include newly generated fields/text.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 247 to 250
"repo": {
"type": "string",
"description": "Target repository in 'owner/repo' format. Required when changes are in a subdirectory checkout (e.g., 'repos/repo-a/'). Must be in the allowed-repos list. If omitted, uses the repository at the workspace root."
"description": "Target repository in 'owner/repo' format. For multi-repo workflows where the target repo differs from the workflow repo, this must match a repo in the allowed-repos list or the configured target-repo. If omitted, defaults to the configured target-repo (from safe-outputs config), NOT the workflow repository. In most cases, you should omit this parameter and let the system use the configured default."
}

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repo parameter description states that omitting repo defaults to the configured target-repo and not the workflow repository. However, getDefaultTargetRepo() falls back to GITHUB_REPOSITORY (and other sources) when target-repo is not set (see actions/setup/js/repo_helpers.cjs:102-120). Please update this description to reflect the conditional behavior (e.g., defaults to target-repo when configured, otherwise defaults to the workflow/current repository).

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +107
let toolToRegister = tool;
// Enrich create_pull_request tool description when target-repo is configured
if (tool.name === "create_pull_request" && config.create_pull_request) {
const targetRepo = config.create_pull_request["target-repo"];
if (targetRepo) {
toolToRegister = JSON.parse(JSON.stringify(tool));
toolToRegister.description += ` Note: This workflow is configured to create pull requests in '${targetRepo}'. You do not need to specify the repo parameter.`;
if (toolToRegister.inputSchema && toolToRegister.inputSchema.properties && toolToRegister.inputSchema.properties.repo) {
toolToRegister.inputSchema.properties.repo.description += ` Configured default: '${targetRepo}'.`;
}

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registerPredefinedTools() clones the create_pull_request tool via JSON.parse(JSON.stringify(tool)) when target-repo is configured. At this point tools already have handler functions attached (see safe_outputs_mcp_server.cjs:47-54), and JSON serialization drops functions—so the registered tool will lose its handler and become non-functional. Use an object/structured clone approach that preserves tool.handler (e.g., shallow clone with spreads and only deep-clone inputSchema.properties.repo), or explicitly copy the handler back onto the cloned object before registering.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pelikhan Yes this code doesn't look right.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good catch. Missed it. It's merged so let's spin a CCA to fix / text this.

@dsyme

dsyme commented Mar 3, 2026

Copy link
Copy Markdown
Collaborator

Yeah I think the bug report is based on an older version - but this PR looks fine and has some additional fixes

@pelikhan

pelikhan commented Mar 3, 2026

Copy link
Copy Markdown
Collaborator

I will do the config.JSON unification later.

@pelikhan pelikhan merged commit 9b38258 into main Mar 3, 2026
146 checks passed
@pelikhan pelikhan deleted the copilot/fix-missing-target-repo-config branch March 3, 2026 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

config.json missing target-repo for create_pull_request in cross-repo workflows

4 participants