Submission requirements
Problem summary
repos: accepts a repository in another Azure DevOps organisation, and the checkout works, but create-pull-request cannot target it. The safe-output executor builds every Git API call from a single AZURE_DEVOPS_ORG_URL + SYSTEM_TEAMPROJECT, so a repository alias belonging to a different organisation resolves against the wrong one and cannot be found.
The result is a workflow that can read a repository — the agent greps it, traces a failure into it, concludes the fix belongs there — and then cannot act on that conclusion. create-pull-request advertises the capability: its repository parameter is documented as "a repository alias from the checkout list", and every alias in repos: is such an alias, whichever organisation it came from.
This is not a permissions problem. In our case the pipeline identity has Read, Contribute, CreateBranch and PullRequestContribute on the cross-organisation repositories, verified with permissionevaluationbatch against that organisation. The credential would work; the URL it is used against is the wrong one.
Reproduction details
Environment: ado-aw 0.50.0, standalone target, engine copilot.
Front matter — three of the four repositories are in msazure/One, two are in msazuredev/AzureForOperatorsIndustry:
repos:
- One/azlocal-overlay
- name: AzureForOperatorsIndustry/nc-api-testing
ref: refs/heads/main
endpoint: afoi-x-org-pipeline
- name: AzureForOperatorsIndustry/nc-resource-testing
ref: refs/heads/main
endpoint: afoi-x-org-pipeline
The checkout succeeds and the agent reads those repositories happily. The executor, however, receives only:
env:
SYSTEM_ACCESSTOKEN: $(SC_WRITE_TOKEN)
ADO_AW_SELF_REPOSITORY_DIRECTORY: $(Build.SourcesDirectory)/self
ADO_AW_SELF_REPOSITORY_NAME: AzureStack-Solution-CI-Infra
ADO_AW_SELF_REPOSITORY_* are the only repository variables the binary knows — strings on the released binary shows no other ADO_AW_*REPOSITORY* names — so a non-self alias has no organisation, project or repository id attached to it, and the request is composed against AZURE_DEVOPS_ORG_URL.
Confirming where the repositories actually live:
GET msazure.visualstudio.com/One/_apis/git/repositories/azlocal-overlay -> 200
GET msazure.visualstudio.com/One/_apis/git/repositories/nc-api-testing -> 404
GET dev.azure.com/msazuredev/AzureForOperatorsIndustry/.../nc-api-testing -> 200
Observed: a pull request cannot be created against a cross-organisation alias.
Expected: create-pull-request can target any repository in repos:, as its repository parameter describes.
Note --dry-run reports success for all of these, because it skips the API calls where the resolution would fail:
[1/3] create-pull-request - ✓ - [DRY-RUN] Would execute: create PR: '...' in repo 'azlocal-overlay'
[2/3] create-pull-request - ✓ - [DRY-RUN] Would execute: create PR: '...' in repo 'nc-api-testing'
So the limitation is invisible until a run genuinely tries, which for a workflow that only raises a PR when confident may be weeks after the pipeline is set up.
Proposed next step
Carry the organisation, project and repository id per checkout alias rather than only for self — the compiler already knows all three from repos:, since it emits the checkout: steps — and have create-pull-request compose its URL from the alias's own context. The service connection named in endpoint: is the natural place to get a credential for that organisation, mirroring how the checkout authenticates.
Failing that, two smaller improvements would each have saved us the investigation:
- Fail at compile time. If
create-pull-request is enabled and repos: contains an alias outside the pipeline's organisation, say so when compiling. The mismatch is fully known then.
- Make
--dry-run resolve the repository. Reporting "would execute" for a target that cannot be resolved is the least useful answer, and dry-run is exactly where this should surface.
Workaround for anyone hitting this: restrict pull requests to same-organisation repositories and have the agent write the proposed change into the work item for the others.
Submission requirements
.github/agents/ado-aw.agent.md.githubnext/ado-aw.Problem summary
repos:accepts a repository in another Azure DevOps organisation, and the checkout works, butcreate-pull-requestcannot target it. The safe-output executor builds every Git API call from a singleAZURE_DEVOPS_ORG_URL+SYSTEM_TEAMPROJECT, so a repository alias belonging to a different organisation resolves against the wrong one and cannot be found.The result is a workflow that can read a repository — the agent greps it, traces a failure into it, concludes the fix belongs there — and then cannot act on that conclusion.
create-pull-requestadvertises the capability: itsrepositoryparameter is documented as "a repository alias from the checkout list", and every alias inrepos:is such an alias, whichever organisation it came from.This is not a permissions problem. In our case the pipeline identity has Read, Contribute, CreateBranch and PullRequestContribute on the cross-organisation repositories, verified with
permissionevaluationbatchagainst that organisation. The credential would work; the URL it is used against is the wrong one.Reproduction details
Environment:
ado-aw0.50.0, standalone target, enginecopilot.Front matter — three of the four repositories are in
msazure/One, two are inmsazuredev/AzureForOperatorsIndustry:The checkout succeeds and the agent reads those repositories happily. The executor, however, receives only:
ADO_AW_SELF_REPOSITORY_*are the only repository variables the binary knows —stringson the released binary shows no otherADO_AW_*REPOSITORY*names — so a non-selfalias has no organisation, project or repository id attached to it, and the request is composed againstAZURE_DEVOPS_ORG_URL.Confirming where the repositories actually live:
Observed: a pull request cannot be created against a cross-organisation alias.
Expected:
create-pull-requestcan target any repository inrepos:, as itsrepositoryparameter describes.Note
--dry-runreports success for all of these, because it skips the API calls where the resolution would fail:So the limitation is invisible until a run genuinely tries, which for a workflow that only raises a PR when confident may be weeks after the pipeline is set up.
Proposed next step
Carry the organisation, project and repository id per checkout alias rather than only for
self— the compiler already knows all three fromrepos:, since it emits thecheckout:steps — and havecreate-pull-requestcompose its URL from the alias's own context. The service connection named inendpoint:is the natural place to get a credential for that organisation, mirroring how the checkout authenticates.Failing that, two smaller improvements would each have saved us the investigation:
create-pull-requestis enabled andrepos:contains an alias outside the pipeline's organisation, say so when compiling. The mismatch is fully known then.--dry-runresolve the repository. Reporting "would execute" for a target that cannot be resolved is the least useful answer, and dry-run is exactly where this should surface.Workaround for anyone hitting this: restrict pull requests to same-organisation repositories and have the agent write the proposed change into the work item for the others.