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 {