Skip to content

Incorrect repodata_record.json precedence for explicit installs #4095

@maresb

Description

@maresb

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:

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions