astrid-runtime/astrid · error
signed Distro.lock members do not match Distro.toml…
Error message
signed Distro.lock members do not match Distro.toml declarations
What it means
validate_signed_member_sets enforces that the signed Distro.lock describes exactly the same set of capsules as the signed Distro.toml: the declared map must have no duplicate names and the lock must contain exactly that many entries. If either check fails, the lock and manifest are inconsistent and the CLI bails rather than trusting partial members.
Solutions
- Regenerate Distro.lock from the current Distro.toml (re-run the distro lock/seal step) and republish both files
- Remove duplicate capsule name declarations in Distro.toml
- Diff the capsule name sets in Distro.toml vs Distro.lock to find the missing/extra entry
Example fix
# before: lock missing capsule capsules = ["alpha"] # toml capsules = ["alpha", "beta"] # stale lock # after capsules = ["alpha"] # toml capsules = ["alpha"] # regenerated lock
Defensive patterns
Strategy: validation
Validate before calling
let toml_names: HashSet<_> = manifest.capsules.iter().map(|c| c.name.clone()).collect(); let lock_names: HashSet<_> = lock.capsules.iter().map(|c| c.name.clone()).collect(); anyhow::ensure!(toml_names.len() == manifest.capsules.len(), "duplicate capsule names in Distro.toml"); anyhow::ensure!(toml_names == lock_names, "Distro.toml and Distro.lock capsule sets differ");
Try / catch
match validate_signed_member_sets(manifest, lock) {
Err(e) if e.to_string().contains("members do not match") => {
eprintln!("Stale lock: regenerate and re-seal Distro.lock from current Distro.toml");
}
r => r?,
} Prevention
- Regenerate Distro.lock whenever Distro.toml changes; never hand-edit either
- Reject duplicate capsule names at manifest authoring time
- Diff toml vs lock capsule name sets in CI before sealing
When it happens
Trigger: fetch_signed_manifest -> verify_signed_manifest -> validate_signed_member_sets when: Distro.toml declares duplicate capsule names (declared.len() < manifest.capsules.len()), or Distro.lock lists a different number of capsules than the manifest declares (extra entries in the lock, or capsules declared in TOML but absent from the lock).
Common situations: Distro.lock regenerated after editing Distro.toml but the stale lock is still published; hand-editing either file; merging branches where capsules were added in TOML but the lock was not refreshed.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- signed Distro.lock contains undeclared capsule
- signed Distro.toml has no [distro.signing] configuration
- astrid distro apply requires a signed Distro…
- capsule archive already contains
- capsule archive contains duplicate entry
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/4f131648334207f5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/init_signed_source.rs:345
})
.collect())
}
/// Require the signed lock to describe exactly the authenticated TOML members.
fn validate_signed_member_sets(manifest: &DistroManifest, lock: &DistroLock) -> anyhow::Result<()> {
if lock.schema_version != manifest.schema_version
|| lock.distro.id != manifest.distro.id
|| lock.distro.version != manifest.distro.version
{
bail!("Distro.lock identity does not match the signed Distro.toml");
}
let declared: HashMap<&str, &DistroCapsule> = manifest
.capsules
.iter()
.map(|capsule| (capsule.name.as_str(), capsule))
.collect();
anyhow::ensure!(
declared.len() == manifest.capsules.len() && lock.capsules.len() == declared.len(),
"signed Distro.lock members do not match Distro.toml declarations"
);
for capsule in &lock.capsules {
let declared_capsule = declared
.get(capsule.name.as_str())
.copied()
.ok_or_else(|| {
anyhow::anyhow!(
"signed Distro.lock contains undeclared capsule '{}'",
capsule.name
)
})?;
if capsule.source != declared_capsule.source || capsule.version != declared_capsule.version
{
bail!(
"signed Distro.lock entry '{}' does not match Distro.toml",
capsule.nameView on GitHub (pinned to affd8760f4)