astrid-runtime/astrid · error
unexpected distro lock response: {other:?}
Error message
unexpected distro lock response: {other:?} What it means
load_lock_from_daemon sends an AdminRequestKind::DistroLockGet request to the kernel daemon and pattern-matches on the reply. The daemon is expected to answer with AdminResponseBody::DistroLock or AdminResponseBody::Error; any other AdminResponseBody variant indicates a protocol mismatch between CLI and daemon (wrong daemon version, mismatched request kind, or deserialization drift). This fallback arm wraps the actual variant in anyhow with a debug dump so the developer can see what came back.
Source
Thrown at crates/astrid-cli/src/commands/distro/lock.rs:162
pub(crate) fn provenance_digest(provenance: &DistroProvenance) -> anyhow::Result<String> {
let bytes = serde_json::to_vec(provenance).context("encode distro provenance")?;
Ok(format!("blake3:{}", blake3::hash(&bytes).to_hex()))
}
/// Read the target principal's durable distro record through the daemon.
pub(crate) async fn load_lock_from_daemon(
principal: &PrincipalId,
) -> anyhow::Result<Option<DistroLock>> {
let mut client = crate::admin_client::connect_as_active_agent().await?;
let response = client
.request(AdminRequestKind::DistroLockGet {
principal: principal.clone(),
})
.await?;
match response {
AdminResponseBody::DistroLock(lock) => Ok((*lock).map(from_provenance)),
AdminResponseBody::Error(error) => Err(anyhow::anyhow!(error)),
other => Err(anyhow::anyhow!(
"unexpected distro lock response: {other:?}"
)),
}
}
/// Replace the target principal's durable distro record with an optimistic
/// compare-and-swap. A missing current record is an intentional create.
pub(crate) async fn write_lock_to_daemon(
principal: &PrincipalId,
lock: &DistroLock,
) -> anyhow::Result<()> {
let mut client = crate::admin_client::connect_as_active_agent().await?;
let current = client
.request(AdminRequestKind::DistroLockGet {
principal: principal.clone(),
})
.await?;
let current = match current {View on GitHub (pinned to affd8760f4)
Solutions
- Restart the astrid daemon so the CLI and daemon binaries are from the same build/version.
- Rebuild/reinstall both CLI and daemon from the same commit (cargo build --workspace or your release pipeline) and retry.
- Read the {other:?} debug dump in the message to identify which AdminResponseBody variant was actually returned and check the daemon's admin response routing for that request kind.
- If the daemon is an older deployment, upgrade it to a version whose DistroLockGet handler returns DistroLock/Error variants the CLI understands.
Example fix
// before (older daemon returns Success for a get)
let response = client.request(AdminRequestKind::DistroLockGet { principal }).await?;
AdminResponseBody::DistroLock(lock) => Ok((*lock).map(from_provenance)),
// after: also accept Success-with-no-body style responses or version-check first
let version = client.hello().await?;
anyhow::ensure!(version.is_compatible_with(env!("CARGO_PKG_VERSION")), "daemon/CLI version mismatch: {version}");
AdminResponseBody::DistroLock(lock) => Ok((*lock).map(from_provenance)), Defensive patterns
Strategy: try-catch
Validate before calling
let v = client.hello().await?;
anyhow::ensure!(v.supports(AdminRequestKind::DistroLockGetMarker), "daemon does not support DistroLockGet (version {v})"); Type guard
fn as_distro_lock(r: &AdminResponseBody) -> Option<&Option<DistroProvenance>> {
match r { AdminResponseBody::DistroLock(l) => Some(l), _ => None }
} Try / catch
match load_lock_from_daemon(&principal).await {
Ok(lock) => lock,
Err(e) if e.to_string().contains("unexpected distro lock response") => {
eprintln!("CLI/daemon version mismatch — restart the daemon");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Restart the daemon whenever you upgrade the CLI so both share one build.
- Add a CLI/daemon version handshake before admin requests.
- Pin CLI and daemon to the same version in deployment tooling.
When it happens
Trigger: Calling load_lock_from_daemon (directly or via regenerate_distro_lock) against a daemon that returns a response variant other than DistroLock or Error for a DistroLockGet request — e.g. AdminResponseBody::Success, an unrelated payload variant, or an empty/unknown variant from an older or newer daemon binary.
Common situations: Running a newer astrid CLI against an older running daemon (or vice versa) whose AdminResponseBody enum gained/lost variants; a daemon bug routing the DistroLockGet reply to the wrong response constructor; stale daemon process not restarted after an upgrade.
Related errors
- unexpected daemon metadata response: {other:?}
- unexpected response while resolving principal UID: {body:?}
- daemon metadata lookup failed: {error}
- unexpected env list response: {response:?}
- daemon rejected capsule install: {message}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/97c1882f795aa823.
Report an issue: GitHub.