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/constrains to the empty list cannot be represented in the local repodata_record.json: the code erases empty lists and refills from index.json, silently undoing the patch.
- Some fields in explicit installs remain wrong in v2.3.3 (
build_number, license, timestamp, and track_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.json should mirror the channel record actually used by the solver, including patches, even when a patch intentionally sets depends/constrains to []. No back-fill from index.json should override an explicit channel decision.
- Explicit installs: writing
repodata_record.json should 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.
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 overinfo/index.json). However, in "explicit installs", the repodata object is a URL-derived stub, not real channel repodata. Making that stub authoritative causedrepodata_record.jsonto 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/constrainsfrom the repodata object so they can be back-filled fromindex.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: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.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
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.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.jsonfor 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:
Even after #4071,
license,timestamp, andtrack_featuresare still clobbered in explicit installs, andconstrainsdisappears. While not demonstrated by this diff,build_numberis also set to zero.