Build1 distinct publisher3 min readUpdated
NU1015 replaces a warning that used to resolve the lowest version on the feed. The same markup is correct under Central Package Management, so the error names a symptom, not an owner.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The diagnostic cannot tell two opposite faults apart, and that is the part worth engineering around. A missing version and a correctly centralised version are the same XML [3]. Restore emits the same NU1015 whether a developer forgot to pin a package or a repository stopped importing the file that pins it, and the NU1015 documentation names the second case directly: a project that expected Central Package Management ended up somewhere CPM is off or its props file is no longer found [4].
The discovery rule is what makes that failure mode easy to hit. NuGet imports only the first `Directory.Packages.props` it encounters while walking up from the project, so a nested props file added for one subtree changes which policy governs everything under it, and a project moved to a new path can lose the import outright [6]. Neither event edits a single project file. That is why the dev.to walkthrough checks evaluated project inputs, neighbouring props files, and recent path changes before touching any package metadata [7]. The timing of the failure is a poor witness: an SDK upgrade surfaces an old direct reference that had always coasted on lowest-version resolution, while a repository reorganisation breaks a CPM import that was valid the day before [8].
The sample feed is where the old behaviour gets priced. It carries Demo.Greeting 1.0.0 and 2.0.0 [9]. Both supported repairs, a pinned `Version` on the reference and a `PackageVersion` in the nearest central file, must resolve and run 2.0.0 [10]. Restore the broken project with `-p:SdkAnalysisLevel=9.0.300 -p:TreatWarningsAsErrors=false` and NU1604 returns, and NuGet picks 1.0.0, the lowest available [11]. A full major version separates the lenient path from the repaired one on a two-package feed [12], which is a fair account of what the warning was permitting in repositories nobody was watching. The author reserves that switch for short migration diagnostics, since it moves every SDK behaviour gated at 9.0.300 along with the one you wanted [13].
The test discipline in the sample is the transferable part. The verifier packs both fixture versions, runs each restore, reads `project.assets.json`, and executes the repaired projects, asserting the resolved version rather than a successful restore [10]. A pasted version and a working CPM import both produce a green restore; only the resolved version tells you which one you shipped.
Two caveats sit on the edges. Repositories that already treat warnings as errors never had the lenient path to begin with, because that policy could promote NU1604 to a failure on its own [14]. And the local-feed sample deliberately skips authenticated sources, source mapping, package lock files, and feed outages [15], all of which sit between a passing fixture and a production restore.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
.NET 10 turns a PackageReference without a version into a restore error, NU1015.
Before .NET 10, NuGet reported NU1604 when a direct reference had no inclusive lower bound; restore could continue and select the lowest version available from the configured sources.
Versionless PackageReference XML is also the correct shape for NuGet Central Package Management, so identical markup is either a missing version or a correct CPM reference depending on whether CPM is active.
The NU1015 diagnostic reference calls out a common failure mode: a project that expected CPM was copied into a location where CPM is disabled or its props file is no longer discovered.
Microsoft documents the NU1604-to-NU1015 change as a stable behavioral change in the .NET 10 compatibility guidance.
NuGet automatically imports only the first Directory.Packages.props it finds while walking up from a project, so a nested file can change which policy applies and a copied project can lose the import completely.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible mechanism, single-publisher attestation
The mechanism is specific, falsifiable, and demonstrated: exact diagnostic codes, the enabling property and nearest-file rule for CPM, a local feed with two fixture versions, and a verifier that reads project.assets.json and executes the repaired projects. The author also self-limits scope and flags the compatibility switch's blast radius, which raises credibility. It is capped because every element rests on one dev.to post; the Microsoft compatibility guidance, NU1015 reference, CPM guide, and merged pull request are described rather than supplied as independent cluster sources, and no third party reproduces the 1.0.0-versus-2.0.0 result.
Shipped SDK default, field impact unmeasured
There is real adoption substance in that the stricter default is described as shipped .NET 10 behavior with a documented compatibility switch, which gives it broad potential reach across any project restoring with the new SDK. But the supplied material contains no usage disclosures, telemetry, issue volumes, repository counts, or third-party deployments; the only concrete runs are the author's own local-feed fixtures. Adoption is therefore scored low and reflects shipped-default status only, not observed field uptake or breakage rates.
Marginally understated
The framing is close to aligned with the evidence and slightly conservative rather than inflated. The headline claim is narrow and code-level, the author explicitly declines to sell the compatibility switch as a fix, lists what the sample does not model, and warns that SdkAnalysisLevel gates more than this diagnostic. The single genuinely striking finding — that the lenient path silently resolves a full major version lower — is presented as a sample observation rather than an ecosystem alarm, which is why the gap tips slightly negative rather than sitting at zero.
Practitioner content incentives, no disclosed commercial stake
The single source is an individual developer-platform post with engagement conventions: a closing reader question and a sign-off, plus links to the author's own sample repository and merged pull request, which creates a mild incentive toward a clean, tidy narrative and self-referential validation. No vendor sponsorship, product being sold, or affiliation with the platform owner is disclosed or evident in the supplied material, and the author argues against the easy fix rather than for a tool, so distorting pressure looks modest.
Moderate
Confidence is moderate: the claims are internally consistent, mechanically checkable, and tied to named diagnostics and documented behavior, which makes them easy for a reader to falsify. It is held below high because the cluster has exactly one publisher, no independent reproduction, and no field data on incidence; the referenced Microsoft documentation and merged pull request are asserted rather than supplied as sources in this cluster.
build
Console JSON is a schema: .NET 10 dropped the duplicate State.Message, and parsers go quiet1 distinct publisher
build
MTP 2.3 writes TRX as tests finish, so a dead test host no longer erases the evidence1 distinct publisher
product
Rillet's $100M reads as proof mid-market ERP is rip-and-replace, mostly at the cheap end1 distinct publisher
build
A UDP packet is now enough: IKEEXT RCE moves from patch queue to fire drill1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 23, 2026