microsoft / microsoft/process-migrator

Process Migrator sends explicit field id during createField, causing VS403734 for fields that Azure DevOps UI can create (e.g. @ in name)

Open Beginner friendly
#116 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
113
Forks
61
PR merge metrics
No merged PRs in 30d

Description

Summary

Process Migrator fails to create certain custom fields with error VS403734, even though the same fields can be created successfully via the Azure DevOps UI.

After investigation, the issue appears to be caused by the payload used during field creation. The migrator sends the exported field id (reference name) back to the API, while the Azure DevOps UI uses a minimal payload (id = null, url = null) and lets the server generate the reference name.

This difference in payload causes stricter backend validation and results in a failure for fields that are otherwise valid.


Error

Example:

Create field 'Custom.TestField@'

VS403734: The work item type field reference name Custom.TestField@ isn't valid as it either uses disallowed characters (must have only letters, no spaces, and at least one period (.)), or has a bad length (must be within 1 - 260 characters long).


What we verified

1. UI creation succeeds

Creating a field in Azure DevOps UI with:

Name: "Test Field @"

works successfully.

The resulting field has:

id: Custom.TestField@


2. UI request payload (working)

POST /_apis/work/processDefinitions/{processId}/fields

Request body:

{
"id": null,
"url": null,
"description": "",
"name": "Test Field @",
"type": 1,
"pickList": null
}

Response:

{
"id": "Custom.TestField@",
"name": "Test Field @",
"type": "string",
...
}


3. Migrator behavior (failing)

Exported field example:

{
"id": "Custom.TestField@",
"name": "Test Field@",
"type": 1,
"description": "",
"url": "...",
"isIdentity": false,
"isLocked": false
}

During import, the migrator sends this id back in the createField call.


4. Root cause

Process Migrator reuses a field read-model as a create-model.

It sends:

  • id (reference name)
  • url

during field creation, instead of letting the backend generate them.

This results in different validation behavior compared to the UI.


5. Local fix (validated)

Changing the create-field payload to match the UI behavior fixes the issue:

  • id: null
  • url: null
  • send only minimal required fields (name, type, description, pickList)

After this change:

  • Fields like Custom.TestField@ are created successfully
  • Migration completes without VS403734

Suggested fix

When calling:

WorkItemTrackingProcessDefinitionsApi.createField(...)

construct a minimal payload similar to the UI:

  • id = null
  • url = null
  • description
  • name
  • type
  • pickList

Then use the returned field id for subsequent operations.


Impact

This blocks migration of inherited processes containing fields whose generated reference names include characters like @, even though Azure DevOps UI supports creating such fields.


Additional notes

A working fix has been implemented and validated in a fork:

https://github.com/sb-devworks/process-migrator/tree/fix-field-create-payload

Happy to provide a pull request if this approach is acceptable.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the import path that calls WorkItemTrackingProcessDefinitionsApi.createField and compare its payload with the minimal Azure DevOps UI payload described here. The work is done when created fields omit the exported id and url, use the returned field id for later operations, and migration succeeds for names such as Custom.TestField@ without VS403734.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, node.js, typescript
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.