Ash
Ash

Reputation: 2294

Why am I getting a 400 - Bad Request when completing a pull request using the VSTS API

I'm guessing this is a permission issue. I know the URI and body, etc are all correct, as it works fine with a different authorisation in the header.

I tried adjusting permissions under _admin/_versioncontrol to 'Allow', as per what had worked for me when creating pull requests. Ref: Getting a '403 Forbidden' when calling the Pull Request API on VSTS

But while I can create/abandon requests just fine, I can't seem to auto-complete them.

What am I missing?

Edit 1 (based on starian chen-MSFT's request):

When I catch the exception in my powershell script and do a Write-Output $_.Exception, I get this:

The remote server returned an error: (400) Bad Request.

When I remove the Invoke-RestMethod from a try-catch block, I get this printed to the consolve output:

2018-03-10T03:22:13.3706092Z Calling https://<my_vsts_account>.visualstudio.com/DefaultCollection/_apis/git/repositories/<my_git_repo_id>/pullRequests/<my_pr_id>?api-version=3.0 with body:
2018-03-10T03:22:13.3727606Z {
2018-03-10T03:22:13.3727838Z     "autoCompleteSetBy":  {
2018-03-10T03:22:13.3728135Z                               "id":  "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
2018-03-10T03:22:13.3728388Z                           },
2018-03-10T03:22:13.3728593Z     "completionOptions":  {
2018-03-10T03:22:13.3728942Z                               "mergeCommitMessage":  "Auto completing pull request",
2018-03-10T03:22:13.3729252Z                               "squashMerge":  "false",
2018-03-10T03:22:13.3729845Z                               "deleteSourceBranch":  "false"
2018-03-10T03:22:13.3730053Z                           }
2018-03-10T03:22:13.3730229Z }
2018-03-10T03:22:13.6040452Z ##[error]Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Invalid argument value.\r\nParameter name: Invalid 
pull request auto complete set by id. Valid values are either the current user identity id, or an empty guid (to unset 
auto complete).","typeName":"Microsoft.TeamFoundation.SourceControl.WebServer.InvalidArgumentValueException, 
Microsoft.TeamFoundation.SourceControl.WebServer","typeKey":"InvalidArgumentValueException","errorCode":0,"eventId":0}
At C:\Development\.agent\scripts\do-ci.ps1:562 char:33
+ ... ry_result = Invoke-RestMethod -Uri $uri -Method Patch -UseDefaultCred ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc 
   eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Once again, when I copy paste the above URI and body into Postman, it works perfectly fine. Seeing that the only difference between my Powershell script and the Postman call is the authorization header, it means this is a permission issue, and a permission issue alone.

Upvotes: 0

Views: 2915

Answers (1)

starian chen-MSFT
starian chen-MSFT

Reputation: 33698

You need to specify the same user id (current authorized user) to update pull request to Auto-Complete through REST API ("autoCompleteSetBy":{"id":xxx}), otherwise you will get 400 error.

You can update pull request status to Completed through REST API if you just want to complete the pull request.

Update:

Simple code to create pull request and get user's id:

param(
[string]$project,
[string]$repo,
[string]$sourceBranch,
[string]$targetBranch,
[string]$title,
[string]$des,
[string]$token
)
$bodyObj=@{
  "sourceRefName"="refs/heads/$sourceBranch";
  "targetRefName"= "refs/heads/$targetBranch";
  "title"= "$title";
  "description"="$des";
}
$bodyJson=$bodyObj| ConvertTo-Json
$uri="https://XXX.visualstudio.com/DefaultCollection/$project/_apis/git/repositories/$repo/pullRequests?api-version=3.0"
Write-Output $bodyJson
Write-Output $uri
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
$result=Invoke-RestMethod -Method POST -Uri $Uri -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyJson
$serviceId=$result.createdBy.id
Write-Host $serviceId
Write-Host "##vso[task.setvariable variable=userId;]$serviceId"

Upvotes: 2

Related Questions