docfx: MergeCommand failing (null pointer exception)

DocFX Version Used: 2.37.0.0

Template used: default

Steps to Reproduce:

  1. Add the following to docfx.json
  "metadata": [
    {
      "src": "*.csproj",
      "dest": "temp/api/netstandard2.0",
      "properties": {
          "TargetFramework": "netstandard2.0"
      }
    },
      {
        "src": "*.csproj",
        "dest": "temp/api/net40",
        "properties": {
            "TargetFramework": "net40"
        }
    },
      {
        "src": "*.csproj",
        "dest": "temp/api/net46",
        "properties": {
            "TargetFramework": "net46"
        }
    }
  ],
  "merge": {
    "content": [
        {
            "files": "*.yml",
            "src": "temp/api/net40"
        },
        {
            "files": "*.yml",
            "src": "temp/api/net46"
        },
        {
          "files": "*.yml",
          "src": "temp/api/netstandard2.0"
        }
    ],
    "fileMetadata": {
        "platform": {
            "temp/api/net40/*.yml": [
                "net40"
            ],
            "temp/api/net46/*.yml": [
                "net46"
            ],
            "temp/api/netstandard2.0/*.yml": [
              "netstandard2.0"
          ]
        }
    },
    "dest": "api"
}
  1. Run docfx.exe metadata
  2. Run docfx.exe docfx.json --serve

Expected Behavior: API documentation generated (i.e. merge command should have moved the files into the api folder)

Actual Behavior: An error was thrown and and the API documentation files were not generated.

[18-07-12 03:10:53.343]Info:[MetadataCommand]Completed Scope:MetadataCommand in 17778.9324 milliseconds.
[18-07-12 03:10:53.387]Info:[MergeCommand.Merge Metadata]Start merge metadata...
[18-07-12 03:10:55.891]Error:[MergeCommand]System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.DocAsCode.Build.Engine.HostServiceCreator.LoadModels(IEnumerable`1 files, DocumentBuildParameters parameters, IDocumentProcessor processor)
   at Microsoft.DocAsCode.Build.Engine.HostServiceCreator.CreateHostService(DocumentBuildParameters parameters, TemplateProcessor templateProcessor, IMarkdownService markdownService, IEnumerable`1 metadataValidator, IDocumentProcessor processor, IEnumerable`1 files)
   at Microsoft.DocAsCode.Build.Engine.SingleDocumentBuilder.Build(IDocumentProcessor processor, DocumentBuildParameters parameters, IMarkdownService markdownService)
   at Microsoft.DocAsCode.SubCommands.MetadataMerger.MergePageViewModel(MetadataMergeParameters parameters)
   at Microsoft.DocAsCode.SubCommands.MetadataMerger.Merge(MetadataMergeParameters parameters)
   at Microsoft.DocAsCode.SubCommands.MergeCommand.MergeDocument(String baseDirectory, String outputDirectory)
[18-07-12 03:10:55.912]Info:[MergeCommand]Completed Scope:MergeCommand in 2568.157 milliseconds.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 5
  • Comments: 17 (7 by maintainers)

Most upvoted comments

Any progress on this? Multi-targeting is the name of the game these days, and the merge command has been broken for at least a year-and-a-half.

@dotMorten thank you for the work-around; i can see, that great minds think a-like 😉

In my frustration over this ooooold bug, I was actually testing out the same way that you presented here … it’s just not as smooth as if they fixed the bug.

My approach - although very similar to yours - was to have multiple docfx.json … one for each target framework and then one containing the actual build configuration.

I will check later which approach is the smoothest … i tend to lean towards your implementation.

Thanks for sharing.

@gimlichael I’ve opted to just generate the doc over and over again for each framework. One benefit of that is that I can actually create doc that’s specific for a platform if I need to. It does have a downside though as it creates a gazillion warnings, and links are wrong. I fix the links with a subsequent powershell command.

Here’s an example of the multi-platform generated doc: https://dotmorten.github.io/NmeaParser/api/index.html

Here’s how I generate for each TFM: https://github.com/dotMorten/NmeaParser/blob/master/docs/docfx.json#L2-L70

Here’s where I call the powershell script after building to fix links: https://github.com/dotMorten/NmeaParser/blob/master/.github/workflows/ghpages.yml#L43 And the powershell script: https://github.com/dotMorten/NmeaParser/blob/master/docs/FixApiRefLinks.ps1

But it really shouldn’t be this hard - even if I would like separate doc for each platform

The bug appears to be here because it parses a null-context into the constructor: https://github.com/dotnet/docfx/blob/27f259127b94dac20186cb6002497ae3dadc63f5/src/Microsoft.DocAsCode.Build.Engine/SingleDocumentBuilder.cs#L34 This later causes a crash here: https://github.com/dotnet/docfx/blob/27f259127b94dac20186cb6002497ae3dadc63f5/src/Microsoft.DocAsCode.Build.Engine/HostServiceCreator.cs#L117

Null is passed in as context, but the code in the class is expecting it to be non-null. Even if you try and do a null-check and just pass 1 as a fallback, it’ll fail later when it gets here: https://github.com/dotnet/docfx/blob/27f259127b94dac20186cb6002497ae3dadc63f5/src/Microsoft.DocAsCode.Build.Engine/LinkPhaseHandler.cs#L96 because that’s also created with a null-context.

This is a good example of why someone should enable nullable checks in their code.

Here’s the quick change I made to SingleDocumentBuilder.cs’s Build command. No crash no (but also no output): image