-
Notifications
You must be signed in to change notification settings - Fork 418
Description
This follows up on #4052 to indicate some problems that still remain.
Summary
Since v2.1.1, libmamba switched in #3901 to "repodata-first" when constructing info/repodata_record.json (intended to honor channel repodata patches over info/index.json). However, in "explicit installs", the repodata object is a URL-derived stub, not real channel repodata. Making that stub authoritative caused repodata_record.json to be written with incomplete/zeroed fields in v2.1.1 through v2.3.2.
In the v2.3.3 release, #4071 attempted to mitigate this by removing empty depends/constrains from the repodata object so they can be back-filled from index.json. However, this is applied unconditionally, based only on emptiness, with no check that the source actually came from an explicit install. As a result:
- Channel repodata patches that intentionally set
depends/constrainsto the empty list cannot be represented in the localrepodata_record.json: the code erases empty lists and refills fromindex.json, silently undoing the patch. - Some fields in explicit installs remain wrong in v2.3.3 (
build_number,license,timestamp, andtrack_features), keeping the cache divergent from the best-known info.
This behavior corrupts the local cache metadata and propagates to tools that rely on repodata_record.json (e.g., conda-lock). Theoretically, this has the risk of leading to incomplete or incorrect lockfiles as in conda/conda-lock#862 (summary). Thankfully, experimentation shows that #4071 was sufficient to resolve a serious bug involving disappearing dependencies, so this issue is far less critical than #4052.
Expected behavior
- Normal channel installs:
repodata_record.jsonshould mirror the channel record actually used by the solver, including patches, even when a patch intentionally setsdepends/constrainsto[]. No back-fill fromindex.jsonshould override an explicit channel decision. - Explicit installs: writing
repodata_record.jsonshould not persist skeletal/placeholder values that zero out fields relative to either channel or artifact metadata.
Concrete example (PyYAML)
As a good baseline, v2.1.0 wrote a more complete repodata_record.json for this package:
{
"arch": null,
"build": "pyh7db6752_0",
"build_number": 0,
"build_string": "pyh7db6752_0",
"channel": "conda-forge",
"constrains": [],
"depends": [],
"fn": "pyyaml-6.0.3-pyh7db6752_0.conda",
"license": "",
"license_family": "MIT",
"md5": "b12f41c0d7fb5ab81709fcc86579688f",
"name": "pyyaml",
"noarch": "python",
"platform": null,
"size": 45223,
"subdir": "noarch",
"timestamp": 0,
"track_features": "",
"url": "https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda",
"version": "6.0.3"
}Since v2.3.3, here is the result for the same artifact after an explicit install:
{
"arch": null,
"build": "pyh7db6752_0",
"build_number": 0,
"build_string": "pyh7db6752_0",
"channel": "conda-forge",
"depends": [
"python >=3.10.*",
"yaml"
],
"fn": "pyyaml-6.0.3-pyh7db6752_0.conda",
"license": "",
"license_family": "MIT",
"md5": "b12f41c0d7fb5ab81709fcc86579688f",
"name": "pyyaml",
"noarch": "python",
"platform": null,
"size": 45223,
"subdir": "noarch",
"timestamp": 0,
"track_features": "",
"url": "https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda",
"version": "6.0.3"
}Diff:
@@ -4,13 +4,12 @@
"build_number": 0,
"build_string": "pyh7db6752_0",
"channel": "conda-forge",
- "constrains": [],
"depends": [
"python >=3.10.*",
"yaml"
],
"fn": "pyyaml-6.0.3-pyh7db6752_0.conda",
- "license": "MIT",
+ "license": "",
"license_family": "MIT",
"md5": "b12f41c0d7fb5ab81709fcc86579688f",
"name": "pyyaml",
@@ -18,8 +17,8 @@
"platform": null,
"size": 45223,
"subdir": "noarch",
- "timestamp": 1758891992558,
- "track_features": "pyyaml_no_compile",
+ "timestamp": 0,
+ "track_features": "",
"url": "https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda",
"version": "6.0.3"
}Even after #4071, license, timestamp, and track_features are still clobbered in explicit installs, and constrains disappears. While not demonstrated by this diff, build_number is also set to zero.