VS402903: The specified value is not convertible to type ReleaseDefinition. Make sure it is convertible to type ReleaseDefinition and try again

Recently one of the customer reported that he is trying to update a variable in an existing release definition and it is failing with above mentioned error. Sandeep Venkata from the team worked on this problem and found a good solution which should be useful for you. Here is the customer script, failure and solution.

Script

# Get the existing release definition (have shortened the example to only highlight the problem)
$definitionid = "45"
$uri = "https://$vstsaccount.vsrm.visualstudio.com/defaultcollection/$project/_apis/release/definitions/$definitionid`?api-version=3.0-preview.1"
$content = Invoke-RestMethod -Uri $uri-Method Get -Headers $headers -ContentType "application/json"

# Update variables (setting these or not does not affect the error)
$content.variables.EnvironmentId="5"
$content.variables.Action="Drop and Create"

# Update the release definition
$json= @($content) | ConvertTo-Json
$content2 = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -ContentType "application/json" -Body $json -Verbose -Debug

Failure

Invoke-RestMethod : {"$id":"1","innerException":null,"message":"VS402903: The specified value is not convertible to type ReleaseDefinition. Make sure it is convertible to type ReleaseDefinition and try again.","typeName":"Microsoft.V
isualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data","typeKey":"InvalidRequestException","errorCode":0,"eventId":3000}

Solution

On the face of it, the above script looks reasonable and Sandeepfound that ConvertTo-Json is not converting the release definition object to JSON format completely and leaving few properties with @ notatation. He observed that by default ConvertTo-Json goes only 2 levels deep and does not convert all the properties of release definition to JSON. The fix here is to specify -Depth parameter with its max value 100 so that the complete definition object is converted to JSON and then it works.

(Update 15th Feb, 2018)  

Recently another customer reported that the below script does not work for him. Vikranth Thati debugged it and observed that in this customer's definition, there is a power-shell task with special characters and to make it work, we have to convert the body to UTF-8 as well.

Here is his working powershell script: -

$vstsaccount = "<accountName>"
$definitionid = "<id>"
$project = "<projectName>"
$personalAccessToken = "<PAT-Token>"

$headers = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)")) }
$uri = "https://$vstsaccount.vsrm.visualstudio.com/defaultcollection/$project/_apis/release/definitions/$definitionid`?api-version=3.0-preview.2"

# GET call to RD
$content = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/json"
Write-Output $content

# Update an existing variable in RD
$content.variables.newVariable.value = "newValue Update of revision " + $content.revision + " at $(Get-Date -format s)"
$jsonContent = $content | ConvertTo-Json -Depth 100
$jsonContent = [Text.Encoding]::UTF8.GetBytes($jsonContent)

# PUT call to RD
$uri = "https://$vstsaccount.vsrm.visualstudio.com/defaultcollection/$project/_apis/release/definitions/$definitionid`?api-version=3.0-preview.2"
$content2 = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -ContentType "application/json" -Body [System.Text.Encoding]::UTF8.GetBytes($jsonContent)   -Verbose -Debug
Write-Output $content2
Enjoy !!