# NousResearch/hermes-agent · Gateway process detection falsely matches CLI ancestor PIDs

## Open now

- Nothing open on GitHub.

These issues and PRs address a bug where the gateway's running-instance detection incorrectly identifies the invoking CLI process (or its ancestor chain) as an already-running gateway. Multiple fix approaches target PID scanning logic to exclude ancestor processes.

## TL;DR

- 6 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 4 PR(s) closed without merging.
- A fix was merged to main in PR #19586. Verify it addresses your case.
- **Recommended:** read PR #19586 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-19586`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.33`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #13242: gateway run detects calling CLI process as running gateway instance (self false positive)

## Prior & competing PRs

- **#19586: fix(gateway): exclude ancestor PIDs from gateway process scan**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `hermes_cli/gateway.py`
  - fix hunks:
  - `hermes_cli/gateway.py`

    ```diff
    @@ -237,6 +237,26 @@ def _graceful_restart_via_sigusr1(pid: int, drain_timeout: float) -> bool:
         return False
     
     
    +def _get_ancestor_pids() -> set[int]:
    +    """Return the set of PIDs in the current process's ancestor chain.
    +
    +    Walks from the current PID up to PID 1 (init) so that process-table scans
    +    never match the calling CLI process or any of its parents.  This prevents
    +    ``hermes gateway status`` from falsely counting the ``hermes`` CLI that
    +    invoked it as a running gateway instance (see #13242).
    +    """
    +    ancestors: set[int] = set()
    +    pid = os.getpid()
    +    # Cap iterations to avoid infinite loops on exotic platforms.
    +    for _ in range(64):
    +        ancestors.add(pid)
    +        parent = _get_parent_pid(pid)
    +        if parent is None or parent <= 0 or parent in ancestors:
    +            break
    +        pid = parent
    +    return ancestors
    +
    +
     def _append_unique_pid(pids: list[int], pid: int | None, exclude_pids: set[int]) -> None:
         if pid is None or pid <= 0:
             return
    ```

    ```diff
    @@ -252,6 +272,10 @@ def _scan_gateway_pids(exclude_pids: set[int], all_profiles: bool = False) -> li
         a live gateway when the PID file is stale/missing, and ``--all`` sweeps can
         discover gateways outside the current profile.
         """
    +    # Exclude the entire ancestor chain so the CLI process that invoked this
    +    # scan (e.g. ``hermes gateway status``) is never mistaken for a running
    +    # gateway.  See #13242.
    +    exclude_pids = exclude_pids | _get_ancestor_pids()
         pids: list[int] = []
         patterns = [
             "hermes_cli.main gateway",
    ```
- **#13250: fix(gateway): exclude CLI invocations from _looks_like_gateway_process (Closes #13242)**. closed without merge
  - maintainer direction: category `silent_close`; implication `active`
- **#13273: fix(gateway): exclude CLI invoker ancestor chain in _append_unique_pid**. closed without merge
  - maintainer direction: category `stale_abandoned`; implication `active`
- **#14177: fix(gateway): ignore invoking CLI ancestor during PID scan**. closed without merge
  - maintainer direction: category `stale_abandoned`; implication `active`
- **#19146: fix: exclude ancestor PIDs from gateway process scan (#13242)**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#19586`

## Fix status

- Merged to main in PR #19586 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-05-04`.
