Skip to content

fix: check container runtime is available in stop and restart - #1036

Merged
xav-db merged 1 commit into
HelixDB:mainfrom
Cintu07:fix/check-runtime-before-container-commands
Aug 26, 2026
Merged

fix: check container runtime is available in stop and restart#1036
xav-db merged 1 commit into
HelixDB:mainfrom
Cintu07:fix/check-runtime-before-container-commands

Conversation

@Cintu07

@Cintu07 Cintu07 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

helix start already checks the container runtime is there before it does anything. if docker is configured but not installed, it stops with an error that names the missing binary and tells you podman is available instead. stop and restart skip that check and spawn the binary directly, so on the same machine they fail with a bare os error.

on a host with podman and no docker, using the container_runtime = "docker" that helix init writes by default:

$ helix start dev
error: Docker is not installed (`docker` not found on PATH)
   │ No such file or directory (os error 2)
   = help: Podman is installed — set `container_runtime = "podman"` under [project] in
     helix.toml to use it instead, or install Docker.

$ helix restart dev
Failed to restart helix-helixproj-dev: No such file or directory (os error 2)

$ helix stop dev
Failed to remove helix-helixproj-dev: No such file or directory (os error 2)

os error 2 never says which binary was missing, so there is nothing in it to act on. you get it on first run too, because init writes docker into helix.toml without looking at what is installed, so a podman user hits this before anything else works.

the fix is already in the file. run_detached and run_foreground both open with Self::check_available(self.runtime)?, and check_available is what routes a spawn failure through not_installed_error to produce the podman hint above. this adds the same line to stop and restart so they land on the error that was already written for this case. no new error text and no new behaviour, two commands just stop bypassing it.

in restart the check sits after the disk and s3 early return, not before it. those paths hand off to run_detached, which already checks, so checking first would probe the daemon twice.

stop and restart are the two commands here that go on to change container state, which is why auto-starting a stopped daemon is reasonable for them, the same as it already is for start. logs and status have the same bare error but they are read only, and check_available will start docker desktop or colima when the binary is present but the daemon is down. starting a daemon as a side effect of reading logs is not something i wanted to slip into this pr. both would be better served by a preflight that checks the binary is installed without auto-starting, which is a different change. happy to send it if you want it.

tested on wsl2, ubuntu 24.04 arm64, podman 4.9.3, docker not installed. after the change both print the same error as start, and with podman configured the normal lifecycle still works: start, status, query, restart, query again, logs, stop.

  • cargo build -p helix-cli
  • cargo clippy -p helix-cli -- -D warnings, clean
  • cargo test -p helix-cli, all suites pass
  • rustfmt --edition 2024 --check crates/cli/src/local_runtime.rs, clean

the typescript_runtime suite needs npm ci in sdks/typescript and node on PATH before it will pass; with those in place it is green here too.

Copilot AI lite review requested due to automatic review settings August 26, 2026 09:28
Comment thread crates/cli/src/local_runtime.rs Outdated
}

pub fn logs(&self, instance_name: &str, follow: bool) -> Result<()> {
Self::check_available(self.runtime)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Logs starts stopped runtime

When helix logs runs with Docker installed but its daemon stopped, check_available starts Docker Desktop, Colima, or the Docker service and waits for startup. This makes a read-only logs command mutate runtime state instead of promptly reporting that the runtime is unavailable.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aligns helix stop, helix restart, and helix logs with helix start by preflighting the configured container runtime so missing-runtime spawn failures are routed through the existing “not installed” error (including the Podman hint) instead of surfacing as a bare OS error.

Changes:

  • Add Self::check_available(self.runtime)? to LocalRuntime::stop().
  • Add Self::check_available(self.runtime)? to LocalRuntime::restart().
  • Add Self::check_available(self.runtime)? to LocalRuntime::logs().

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 324 to 328
pub fn restart(&self, instance_name: &str, config: &LocalInstanceConfig) -> Result<()> {
Self::check_available(self.runtime)?;
if config.storage.is_disk() || config.storage.is_s3() {
return self.run_detached(instance_name, config);
}
Comment thread crates/cli/src/local_runtime.rs Outdated
}

pub fn logs(&self, instance_name: &str, follow: bool) -> Result<()> {
Self::check_available(self.runtime)?;
@Cintu07
Cintu07 force-pushed the fix/check-runtime-before-container-commands branch from 292c32e to aafc8dd Compare August 26, 2026 09:59
run_detached and run_foreground both call check_available before they
touch the runtime, which routes a missing binary through
not_installed_error and produces an actionable message. stop and restart
spawned the binary directly, so on a host without the configured runtime
they failed with a bare os error 2 that does not name what was missing.

restart checks only on the branch that spawns the runtime itself; the
disk and s3 paths return early into run_detached, which already checks.
@Cintu07
Cintu07 force-pushed the fix/check-runtime-before-container-commands branch from aafc8dd to cb749ed Compare August 26, 2026 10:11
@Cintu07 Cintu07 changed the title fix: check container runtime is available in stop, restart and logs fix: check container runtime is available in stop and restart Aug 26, 2026
@Cintu07

Cintu07 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

both fair, and the second one caught an inconsistency in my own reasoning. fixed in cb749ed.

on the redundant probe in restart: the check now sits after the disk and s3 early return, so it only guards the branch that spawns the runtime itself. those paths fall through to run_detached, which already checks, so there is no longer a double probe.

on logs auto-starting the daemon: you are right and i was applying two different standards. i had already left status alone on the grounds that a read only command should not start docker desktop as a side effect, and logs is just as read only. i have dropped it from this pr, so this is now stop and restart only, which are the two commands that go on to change container state and where auto-start matches what start already does.

that does leave logs and status printing the bare os error 2. the right fix for those is the lighter preflight you describe, checking the binary is installed without going near try_start_runtime, which not_installed_error already supports since it takes the installed-probe as a parameter. that is a separate change and i am happy to send it if the maintainers want it.

@xav-db
xav-db merged commit c435777 into HelixDB:main Aug 26, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants