fsprojects / fsprojects/Paket

`paket update` crashes when a project contains a target that manipulates references

Open
#3,794 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
F#
Stars
2.1k
Forks
528
Avg merge
1d 12m
Merged PRs (30d)
54

Description

Description

I have a project file which contains the following target:

  <Target Name="Workaround31298" Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.7.2'">
    <!-- This target is a workaroud for https://github.com/dotnet/runtime/issues/31298 -->
    <ItemGroup>
      <Reference Remove="System.IO.FileSystem.Primitives" />
    </ItemGroup>
  </Target>
  <Target Name="BeforeResolveReferences" DependsOnTargets="Workaround31298"/>

Background for those interested, but irrelevant for this issue: This project consumes, indirectly, System.IO.Packaging. This package declares empty dependencies for netstandard20 and for net461 it requires System.IO.FileSystem.Primitives. My project targets net472 and Paket considers the net461 dependency branch (this it is inline with nuget.exe). So my project gets a reference to this fs.primitives.dll, too. Unfortunately, the latest version of this System.IO.FileSystem.Primitives package contains an older version of the dll then the net472 facade, which is installed as part of the .NET Framework. The build system detects this and replaces the reference. But because the replacement is a framework dll it does not get copied into the output dir. This again breaks the incremental build over and over again as the dll is missing from the out dir. So to get the incremental build working again, I use this target to remove the unneeded reference.
I did not manually remove the actual reference inserted by Paket, because this one would be recreated on the next update/install. Never mess with generated code.

When I now perform a paket update everything works fine up to the point where paket touches the project files. There it crashes.

Repro steps
  1. Place the above msbuild snipped inside an arbitrary C#-Project (below the import of "Microsoft.CSharp.targets")

  2. run paket update (or paket install, this doesn't matter)

Expected behavior

The update should run through.
Paket should ignore the "Reference" items inside targets.

Actual behavior

Tested with paket 5.181.1 as well as 5.242.1.

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at Paket.ProjectFileModule.getCustomModelNodes@665.Invoke(XmlNode node)
   at Microsoft.FSharp.Primitives.Basics.List.filter[T](FSharpFunc`2 predicate, FSharpList`1 l)
   at Paket.ProjectFileModule.deleteCustomModelNodes(InstallModel model, ProjectFile project)
   at Paket.ProjectFileModule.contexts@1202-9.Invoke(KeyValuePair`2 kv)
   at Microsoft.FSharp.Collections.Internal.IEnumerator.map@74.DoMoveNext(b& curr)
   at Microsoft.FSharp.Collections.Internal.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable`1 source)
   at Microsoft.FSharp.Collections.SeqModule.SortBy@1108.Invoke(Unit unitVar0)
   at Microsoft.FSharp.Collections.SeqModule.mkDelayedSeq@468.Invoke(Unit unitVar0)
   at Microsoft.FSharp.Collections.SeqModule.revamp@573.Invoke(Unit unitVar0)
   at Paket.ProjectFileModule.updateReferences[a,b,c](FSharpMap`2 completeModel, FSharpMap`2 directPackages, FSharpMap`2 usedPackages, ProjectFile project)
   at Paket.InstallProcess.InstallIntoProjects[a](InstallerOptions options, Boolean forceTouch, DependenciesFile dependenciesFile, LockFile lockFile, FSharpList`1 projectsAndReferences, FSharpMap`2 updatedGroups)
   at Paket.UpdateProcess.SmartInstall(DependenciesFile dependenciesFile, UpdateMode updateMode, UpdaterOptions options)
   at <StartupCode$Paket-Core>.$PublicAPI.UpdatePackage@371-3.Invoke(Unit unitVar0)
   at Paket.Utils.RunInLockedAccessMode[a](String lockedFolder, FSharpFunc`2 action)
   at Paket.Program.handleCommand@827-16.Invoke(ParseResults`1 results)
   at Paket.Program.processWithValidationEx$cont@42[a](Boolean silent, FSharpFunc`2 commandF, a result, Unit unitVar)
   at Paket.Program.processWithValidation[T](Boolean silent, FSharpFunc`2 validateF, FSharpFunc`2 commandF, ParseResults`1 result)
   at Paket.Program.handleCommand(Boolean silent, Command command)
   at Paket.Program.main()
   at <StartupCode$paket>.$Paket.Program.main@()
Segmentation fault
Known workarounds
  1. Rename the item in the above msbuild snipped from "Reference" to "Foo". (It does not help remove a dummy reference, i.e. that fact that System.IO.FileSystem.Primitives was inserted by paket is irrelevant.)
  2. run paket update
  3. rename the item back

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 by locating Paket.ProjectFileModule.getCustomModelNodes and deleteCustomModelNodes, which appear in the reported stack trace. Reproduce with the shown MSBuild Target containing a Reference item, then run paket update or paket install. Done means project-file updates complete without a NullReferenceException and Reference items inside targets are ignored.

Written by the indexing model from the issue text.

Assessment

Tech stack
fsharp
Domain
build-system, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.