Skip to content

Profile deletion is ineffective — profiles and gateways are immediately recreated #1633

Description

@kosmo888

Summary

Deleting a Hermes profile through any available method (Web UI API, hermes profile delete --yes, manual directory removal) does not actually delete the profile. The profile directory and its gateway process are immediately recreated within seconds.

Steps to Reproduce

  1. Have multiple profiles with running gateways
  2. Delete a profile via Web UI: DELETE /api/hermes/profiles/{name} → returns {"success":true}
  3. Or via CLI: hermes profile delete {name} --yes → reports success
  4. Observe: profile directory reappears, gateway process respawns within seconds

Current Behavior

  • DELETE /api/hermes/profiles/{name} returns {"success":true} but the profile persists on disk and in hermes profile list
  • hermes profile delete --yes reports success but the profile persists
  • Manually rm -rf the profile directory and kill -9 the gateway — both are recreated within seconds
  • Setting gatewayAutoStart.enabled = false via config API does not stop existing gateways from respawning

Root Cause Analysis

Three independent mechanisms fight against profile deletion:

1. gateway-runner.ts respawn loop

startGatewayRunManagedInternal() spawns gateways with detached: true and registers an exit handler that respawns the gateway up to MAX_RESPAWN_ATTEMPTS (3) times with a RESPAWN_DELAY_MS (2s) delay. When a profile is deleted and its gateway is killed, the exit handler fires and schedules a respawn. There is no mechanism to tell the runner "this profile is being deleted, don't respawn."

2. ensureProfileGatewaysRunning() in gateway-autostart.ts

Called at Web UI startup (both startRuntimeServicesBeforeListen and startRuntimeServicesAfterListen), this function calls listProfileNamesFromDisk() which scans $HERMES_HOME/profiles/ for directories, then starts a gateway for each discovered profile. Even if gatewayAutoStart.enabled is set to false, the existing gateways that were already spawned by the gateway-runner continue to respawn.

3. container_boot.py s6 reconciliation

On container restart, 02-reconcile-profiles walks $HERMES_HOME/profiles/ and recreates s6 service slots. It reads gateway_state.json — if desired_state is missing, it falls back to gateway_state. Since most profile state files only have gateway_state: "running" (no desired_state field), the reconciler treats them as "should be running" and auto-starts them.

Expected Behavior

Deleting a profile should:

  1. Stop the associated gateway process
  2. Remove the profile directory from disk
  3. Prevent the gateway from being respawned
  4. The profile should not reappear in hermes profile list

Proposed Fix Direction

  1. gateway-runner.ts: When a profile is being deleted, clear the respawn state for that profile before killing the gateway
  2. gateway-autostart.ts: Respect gatewayAutoStart.enabled = false for already-running gateways, not just for initial startup
  3. container_boot.py: When desired_state is absent from gateway_state.json, default to stopped rather than falling back to gateway_state (which may be stale)
  4. Profile delete flow should be atomic: set desired_state: stopped → kill gateway → clear respawn state → remove directory

Environment

  • Hermes Web UI running in Docker (s6-overlay)
  • Multiple profiles with per-profile gateways
  • HERMES_WEB_UI_MANAGED_GATEWAY=1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions