From 3a69ad4256e78a1b483d93b6d78d2796550fc80d Mon Sep 17 00:00:00 2001 From: damocles Date: Mon, 10 Aug 2026 20:55:38 +0200 Subject: [PATCH] hivectl: error on pause/resume of a non-existent agent --- hivectl/src/agents.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hivectl/src/agents.rs b/hivectl/src/agents.rs index 776ace6f..af9e9305 100644 --- a/hivectl/src/agents.rs +++ b/hivectl/src/agents.rs @@ -204,7 +204,19 @@ pub(crate) async fn agents_list(socket: &Path, json: bool) -> Result<()> { /// `hivectl agent pause|resume` — flip the agent's pause marker. Not a /// DAG, so there's nothing to wait on: the daemon writes the marker and /// the harness picks it up on its next poll. +/// +/// Checks existence first, same as `agents_start` above — the daemon side +/// (`Coordinator::set_paused`) writes the marker file unconditionally via +/// the priv-helper and has no notion of "no such agent", so without this +/// check `hivectl agent typo-name resume` would exit 0 and print +/// `resumed: typo-name` for a name that was never a real agent. async fn set_paused(socket: &Path, name: &str, paused: bool) -> Result<()> { + if !crate::util::agent_exists(socket, name).await? { + bail!( + "no such agent: '{name}' (no state dir under {}/)", + hive_host_sock::AGENTS_ROOT + ); + } let resp = crate::client::request( socket, HostRequest::SetPaused {