Skip to content

[Bug]: Inconsistent behavior between work item type validator tool and field mapping #3151

Description

@poke

Version

  • I confirm that I am using the latest version

Source Version

Azure DevOps Server 2022

Target Version

Azure DevOps Service

Relevant configuration

{
  // …
  "FieldMappingTool": {
    "Enabled": true,
    "FieldMaps": [
    {
      "FieldMapType": "FieldValueMap",
      "ApplyTo": ["User Story"],
      "sourceField": "System.State",
      "targetField": "System.State",
      "defaultValue": "New",
      "valueMapping": {
        "New": "New",
        "Active": "Committed",
        "Resolved": "Done",
        "Closed": "Done",
        "Removed": "Removed"
      }
    }
  }
}

Relevant log output

[INF] [16.3.3] Start validation of work item type 'User Story'. 
[INF] [16.3.3]   Work item type 'User Story' is mapped to 'Product Backlog Item'. 
[INF] [16.3.3]   Validating source field 'System.State' (State). 
[INF] [16.3.3]     Missing values are: 'Active', 'Closed', 'Resolved' 
[WRN] [16.3.3]     Source field 'System.State' and target field 'System.State' have different allowed values. 
[INF] [16.3.3]       Source allowed values: 'Active', 'Closed', 'New', 'Removed', 'Resolved' 
[INF] [16.3.3]       Target allowed values: 'Approved', 'Committed', 'Done', 'New', 'Removed' 
[INF] [16.3.3]       Missing values in target are: 'Active', 'Closed', 'Resolved'

What happened?

I’m currently working on a migration where I’m moving from the agile process to the scrum process, so I have to change the work item type during the migration. While testing out my configuration, I noticed some inconsistent behavior in the field mapping that caused my migration to fail.

As you can see from the configuration, I have a field value mapping for System.State for the work item type User Story, which I map to the work item type Product Backlog Item.

This is the correct way to configure this, because the field mapping tool uses the work item type of the source element when looking up the field mappings:

public void ApplyFieldMappings(WorkItemData source, WorkItemData target)
=> ProcessFieldMapList(source, target, GetFieldMappings(source.Fields["System.WorkItemType"].Value.ToString()));

However, when running this, I still get an error that there are missing values in the target type. While browsing the source code to figure out what is wrong, I noticed the validator had been extended in #3010 to support the configured field value mappings but for some reason it was not respecting my configuration.

After going deeper into the code, I realized that while the field mapping itself uses the source work item type, the work item type validator uses the target work item type instead:

fieldResult = ValidateField(sourceField, fieldPair.TargetField, targetWit.Name, logLevel);

Log.LogDebug(" Allowed values in target field do not match allowed values in source. Checking field value maps.");
LogAllowedValues(" Missing values are: {missingValues}", missingValues);
List<string> mappedValues = [];
Dictionary<string, string> valueMaps = _commonTools.FieldMappingTool
.GetFieldValueMappings(targetWitName, sourceFieldReferenceName, targetFieldReferenceName);
foreach (string missingValue in missingValues)
{
if (valueMaps.TryGetValue(missingValue, out string mappedValue))
{

After realizing that, I extended my field value map configuration to also apply to Product Backlog Item (in addition to User Story), and the validation and the migration works as expected.

In my case, this is not an issue since I have a limited set of data for which I do not need more control over the work item types. But I can imagine that this could be a problem where you do not want to have a single state mapping for the target type because you might have multiple source work item types map to the same target type, requiring you to use different mappings.

So I would suggest to unify this behavior and change the work item type validator to also respect the field mappings of the source type.

Debug in Visual Studio

  • Visual Studio Debug

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    To do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions