Circular reference detector and package.config ordering

Apr 20, 2012 at 4:00 AM

I work with a large project with a lot of dependencies and recently we've moved to nuget to help manage the mess. It's been alright so far, but I've found one issue.

If you have packages a and b referenced by project c, and package b also references a the order they're referenced in packages.config matters. I haven't found this documented anywhere. It seems that nuget normally saves the order correctly, but once it didn't and we got rather confused.

If you reference b before a, when a is visited the circular reference detector fires. If a is first it's all OK.

I have a prototype fix for this which uses quickgraph to create a dependency graph and detect cycles on that. I haven't checked performance yet though. I'm currently tidying this up.

Apr 20, 2012 at 4:06 PM

One note, we're moving the source code to a Git repo (, and won't be taking new pull requests until the move is finished. Please wait to send the pull request until then.

Apr 20, 2012 at 5:26 PM

Could you give us a repro step of the problem you ran into? Listings in packages.config are sorted based on Id - its not meant to be order preserving.

Apr 21, 2012 at 10:39 PM

I don't have the exact file to hand - it's in the office and I don't have a Windows development environment at home, but it was like this:



The version numbers were like that for some test work, normally the numbers are actually set to the build number on the CI server.


Using nuget 1.7 the order was definitely important. The project had about 10 packages managed via Nuget with the model/modeldbspecific at the bottom. This resulted in a rather long error claiming that every package was in a cycle, but when I moved them to the top it only output those two packages.

May 14, 2012 at 6:04 AM
Edited May 14, 2012 at 6:31 AM

OK, I've finally had time to get back on to this, and have found the root cause.

In PackageWalker.cs if a dependency cannot be resolved but it is not set to skip dependency errors the function simply returns. This leaves the package currently being checked in the Processing state. If another package that hasn't been checked yet then references the package that referenced the failed dependency NuGet incorrectly returns this as a cycle error.

I think in this case an exception should be thrown instead of simply continuing resolution. I suspect in most cases the current behaviour works, but with the Pack command it continues on, leading to the cycle errors.

I've made the change but it breaks some unit tests as some other walkers expect to get their own dependency walker that follows the current behaviour. If throwing an exception is considered correct I'll look at the other areas that fail and fix them.

Jan 28, 2013 at 1:10 PM


I'm interested in working on this issue, for which has been opened.

(I've attached a test case to it)

However I'd like to get some feedback on the expected behavior: what should "nuget pack xx.csproj" do, when the packages listed in packages.config do not fulfill all dependencies (i.e. some dependencies of the listed packages are missing?)

(a) Should dependency detection fail (because it could be unreliable), and a error message be shown telling which dependencies are missing ?


(b) Should "nuget pack" ignore the missing dependency and proceed with dependency detection anyway ?


I'm thinking (a) is probably the best option and most useful/robust one as it helps developer fix their packages.config should a problem arise.

Jan 29, 2013 at 10:26 AM

I agree that option (a) is the better choice. Please go ahead with #2965. Thanks for contributing.

Jan 31, 2013 at 2:36 PM

Just pointing out that I've published a pull request for this :
Mar 4, 2013 at 3:20 PM
Hi dotnetjunky,

Any idea when this might be merged ?
Let me know if I might help in any way.
Mar 4, 2013 at 3:41 PM
Sorry for the delay. Your pull request is scheduled for the 2.4 release. Right now we're still working on 2.3. I'll look at it next week. Thanks for your patience :)
Apr 2, 2013 at 3:12 PM
Hi dotnetjunky,

I started looking at porting the pull request over to 2.4.

There is indeed some conflict with the work to support packing referenced projects ( ).

It raises some questions:
  • what should happen when the same package is referenced in different projects ?
I suggest the following:
  • If the package reference version is different among the projects, then throw an error
  • If version constraints are defined, intersect the constraints, and throw an error if the intersection is empty
  • If target frameworks are different, throw an error
  • A package reference is NOT a "development dependency" except if it so in all projects which refer to it (the values are AND-ed together).
It it all seems reasonable I'll go ahead with the implementation.
I will probably add some code in VersionUtility to help with intersecting version constraints, as it would now be needed in several places (once for 'aggregating' references version constraints, once for 'aggregating' dependency version constraints).