Migration Report Format

April 7, 2026 · View on GitHub

After running the CLI tool, a migration-report.json file is generated with detailed information about the transformation. This document describes the report schema and how to interpret it.

Report Structure

The report is a JSON document with the following top-level fields:

{
  "migrationDate": "2026-04-02T15:30:45Z",
  "sourceProject": "/home/user/MyApp.Web",
  "outputProject": "/home/user/MyApp.Blazor",
  "projectName": "MyApp.Blazor",
  "projectFramework": "net8.0",
  "toolVersion": "1.0.0",
  "summary": {
    "totalFiles": 45,
    "filesProcessed": 42,
    "filesFailed": 0,
    "filesSkipped": 3,
    "totalTransforms": 1247,
    "totalManualItems": 156,
    "criticalIssues": 5,
    "warnings": 18,
    "infos": 133
  },
  "files": [ /* array of file results */ ],
  "manualItems": [ /* array of manual work items */ ],
  "categories": [ /* grouped manual items by TODO category */ ]
}

Summary Section

FieldTypeDescription
migrationDatestring (ISO 8601)When the migration was run
sourceProjectstringPath to original Web Forms project
outputProjectstringPath to new Blazor project
projectNamestringName of the generated Blazor project
projectFrameworkstringTarget framework (e.g., net8.0)
toolVersionstringCLI tool version
summary.totalFilesintegerTotal .aspx, .ascx, .master files found
summary.filesProcessedintegerFiles successfully converted
summary.filesFailedintegerFiles with conversion errors
summary.filesSkippedintegerFiles not processed (e.g., excluded)
summary.totalTransformsintegerTotal transforms applied across all files
summary.totalManualItemsintegerNumber of TODO comments inserted
summary.criticalIssuesintegerCount of severity="Error" items
summary.warningsintegerCount of severity="Warning" items
summary.infosintegerCount of severity="Info" items

Files Array

Each file in the files array represents a processed source file:

{
  "sourceFile": "Pages/Product.aspx",
  "outputFile": "Pages/Product.razor",
  "fileType": "Page",
  "status": "Success",
  "linesAdded": 12,
  "linesRemoved": 8,
  "transformsApplied": [
    {
      "name": "PageDirective",
      "count": 1,
      "description": "Converted <%@ Page %> to @page"
    },
    {
      "name": "ExpressionTransform",
      "count": 5,
      "description": "Converted <%: %> expressions to @()"
    }
  ],
  "manualItems": [
    {
      "line": 45,
      "category": "bwfc-datasource",
      "severity": "Warning",
      "message": "DataSourceID='ProductSource' → wire Items binding and data service"
    }
  ]
}

File Fields

FieldTypeDescription
sourceFilestringRelative path in Web Forms project
outputFilestringRelative path in Blazor project
fileTypestring"Page", "Control", "Master"
statusstring"Success", "Warning", "Error", "Skipped"
linesAddedintegerNew lines in output (includes TODO comments)
linesRemovedintegerLines removed during conversion
transformsAppliedarrayList of transforms run on this file
manualItemsarrayTODO comments with line numbers

ManualItem Schema

Each manualItem represents a TODO comment that requires manual follow-up:

{
  "file": "Pages/Product.aspx",
  "line": 45,
  "column": 0,
  "category": "bwfc-datasource",
  "severity": "Warning",
  "message": "DataSourceID attribute detected — implement IProductDataService and wire Items binding",
  "suggestion": "// TODO(bwfc-datasource): Replace DataSourceID with Items=\"@ProductList\" and create data service",
  "relatedTransforms": ["DataSourceIdTransform", "SelectMethodTransform"]
}

ManualItem Fields

FieldTypeDescription
filestringRelative file path
lineintegerLine number in output file
columnintegerColumn number (0-based)
categorystringTODO category slug (e.g., bwfc-lifecycle)
severitystring"Info", "Warning", "Error"
messagestringHuman-readable description
suggestionstringCode suggestion or TODO template
relatedTransformsarrayTransforms that created this item

Severity Levels

SeverityMeaningAction
ErrorBlocking issue — project likely won't compileFix immediately
WarningCode will compile but behavior may differReview before building
InfoGuidance comment — migrate at your paceReference during L2 automation

Categories Summary

The categories section groups manual items by TODO category:

{
  "categories": [
    {
      "category": "bwfc-lifecycle",
      "count": 8,
      "severity": "Warning",
      "files": [
        "Pages/Product.aspx",
        "Pages/Checkout.aspx"
      ],
      "description": "Page lifecycle methods need conversion to Blazor component lifecycle"
    },
    {
      "category": "bwfc-datasource",
      "count": 12,
      "severity": "Info",
      "files": [
        "Pages/Product.aspx",
        "Pages/Search.aspx",
        "Controls/ProductCard.ascx"
      ],
      "description": "Data binding patterns need to be replaced with component data services"
    }
  ]
}

Category Summary Fields

FieldTypeDescription
categorystringTODO category slug
countintegerNumber of items in this category
severitystringHighest severity in this category
filesarrayFiles affected (unique list)
descriptionstringWhat needs to be done

Example Report Output

Minimal Success Report

{
  "migrationDate": "2026-04-02T14:30:00Z",
  "sourceProject": "./MyApp.Web",
  "outputProject": "./MyApp.Blazor",
  "projectName": "MyApp.Blazor",
  "toolVersion": "1.0.0",
  "summary": {
    "totalFiles": 5,
    "filesProcessed": 5,
    "filesFailed": 0,
    "filesSkipped": 0,
    "totalTransforms": 87,
    "totalManualItems": 12,
    "criticalIssues": 0,
    "warnings": 3,
    "infos": 9
  },
  "files": [
    {
      "sourceFile": "Default.aspx",
      "outputFile": "Pages/Index.razor",
      "fileType": "Page",
      "status": "Success",
      "linesAdded": 3,
      "linesRemoved": 2,
      "transformsApplied": [
        {"name": "PageDirective", "count": 1},
        {"name": "ExpressionTransform", "count": 6},
        {"name": "AspPrefixTransform", "count": 4}
      ],
      "manualItems": [
        {
          "line": 12,
          "category": "bwfc-datasource",
          "severity": "Info",
          "message": "Review data binding pattern"
        }
      ]
    }
  ],
  "categories": [
    {
      "category": "bwfc-datasource",
      "count": 4,
      "severity": "Info",
      "files": ["Default.aspx"]
    }
  ]
}

Report with Errors

{
  "summary": {
    "totalFiles": 10,
    "filesProcessed": 8,
    "filesFailed": 2,
    "filesSkipped": 0,
    "totalManualItems": 45,
    "criticalIssues": 3,
    "warnings": 15,
    "infos": 27
  },
  "files": [
    {
      "sourceFile": "Controls/CustomControl.ascx",
      "outputFile": "Components/CustomControl.razor",
      "fileType": "Control",
      "status": "Error",
      "statusMessage": "Parser error on line 34: unmatched closing tag",
      "manualItems": [
        {
          "line": 34,
          "severity": "Error",
          "category": "bwfc-general",
          "message": "Malformed markup — review original file for syntax errors"
        }
      ]
    }
  ]
}

How to Use the Report

1. Review Critical Issues First

# Filter for errors (blocks compilation)
jq '.manualItems[] | select(.severity == "Error")' migration-report.json

# Count by category
jq 'group_by(.category) | map({category: .[0].category, count: length})' \
  <(jq '.manualItems[] | select(.severity == "Error")' migration-report.json)

2. Check Summary Statistics

# Print summary
jq '.summary' migration-report.json

3. Find Work by Category

# All lifecycle TODOs
jq '.manualItems[] | select(.category == "bwfc-lifecycle")' migration-report.json

# All warnings grouped by category
jq 'group_by(.category) | map({category: .[0].category, count: length})' \
  <(jq '.manualItems[] | select(.severity == "Warning")' migration-report.json)

4. Build a Worklist

# Export TODOs for a specific file
jq '.manualItems[] | select(.file == "Product.aspx")' migration-report.json | \
  jq -s 'sort_by(.line)' | \
  jq '.[] | "\(.line): [\(.severity)] \(.category) - \(.message)"'

5. Track Automation Progress

# Before L2 automation
jq '.summary' migration-report-before.json

# After L2 automation (lifecycle conversion)
jq '.summary' migration-report-after-lifecycle.json

# Calculate improvement

Report Interpretation Guide

What Errors Mean

ErrorCauseResolution
Parser error: unmatched closing tagMalformed markup in sourceReview original .aspx/.ascx file for syntax errors
File not foundReferenced include or code-behind missingCheck project file references
Unsupported directiveWeb Forms-specific directive without Blazor equivalentManual conversion needed

What Warnings Mean

WarningMeaningAction
DataSourceID detectedNeeds data service wiringImplement L2 datasource automation
ViewState usage foundState pattern conversion neededCreate component fields or parameters
Complex IsPostBack guardHard to unwrap automaticallyReview unwrapped code, may need manual adjustment

What Infos Mean

InfoMeaningAction
TODO comment insertedGuidance for developerReview alongside code during L2 automation
Pattern detectedRecognized Web Forms patternL2 skill can automate this

Example Workflow: Using the Report to Plan L2 Automation

#!/bin/bash

# 1. Run initial migration
webforms-to-blazor migrate --input ./MyApp.Web --output ./MyApp.Blazor

# 2. Check what needs manual work
echo "=== CRITICAL ISSUES ==="
jq '.summary.criticalIssues' MyApp.Blazor/migration-report.json

# 3. Fix errors first
if [ $(jq '.summary.criticalIssues' MyApp.Blazor/migration-report.json) -gt 0 ]; then
  echo "Fixing critical issues..."
  jq '.manualItems[] | select(.severity == "Error")' MyApp.Blazor/migration-report.json
fi

# 4. Plan L2 passes by category count
echo "=== WORK BY CATEGORY ==="
jq '.categories | sort_by(-(.count)) | .[] | "\(.count) x \(.category)"' MyApp.Blazor/migration-report.json

# 5. Run L2 for high-impact categories
# (Use Copilot L2 skills for each category)
copilot /webforms-migration --focus bwfc-lifecycle
copilot /webforms-migration --focus bwfc-datasource
copilot /webforms-migration --focus bwfc-validation

# 6. Generate updated report
webforms-to-blazor migrate --input ./MyApp.Web --output ./MyApp.Blazor --dry-run > migration-report-updated.json

Next Steps