End-of-run cleanup SIGTERMs unrelated processes machine-wide (substring match on "python"/"torch"/"mp" cmdlines)

Author: GoldenmonstewCreated Jun 12, 2026Updated Jun 12, 2026

Related issues: no existing issue found mentioning psutil, the keyword sweep, or cross-run process kills (searched: psutil, kill, cleanup, parallel).

Summary

The final cleanup in launch_scientist_bfts.py first terminates the launcher's own child tree (correct), but then does an additional sweep over every process on the machine, killing any process whose command line contains one of the substrings "python", "torch", "mp", "bfts", "experiment". This kills processes that have nothing to do with the run — most damagingly, other concurrent AI-Scientist runs: when running multiple ideas in parallel on one machine, the first run to finish kills all the others mid-flight.

Where

launch_scientist_bfts.py, lines 321–369 at current main (96bd516). The problematic sweep is lines 347–359:

python
    # Additional cleanup: find any orphaned processes containing specific keywords
    keywords = ["python", "torch", "mp", "bfts", "experiment"]
    for proc in psutil.process_iter(["name", "cmdline"]):
        try:
            # Check both process name and command line arguments
            cmdline = " ".join(proc.cmdline()).lower()
            if any(keyword in cmdline for keyword in keywords):
                proc.send_signal(signal.SIGTERM)
                proc.wait(timeout=3)
                if proc.is_running():
                    proc.kill()
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.TimeoutExpired):
            continue

Specific problems:

  1. psutil.process_iter iterates all processes, not the run's descendants. The legitimate child cleanup has already happened just above (lines 326–345 collect current_process.children(recursive=True) and terminate them), so this sweep only ever hits non-children.
  2. Substring matching is extremely broad. "python" matches every Python process owned by the user (other AI-Scientist launches, notebooks, editors' language servers, schedulers). "mp" matches any cmdline containing /tmp/, mpv, compute, import, etc.
  3. The sweep matches the launcher process itself (its own cmdline contains python ... launch_scientist_bfts.py), so the process SIGTERMs itself partway through the loop — sys.exit(0) at line 369 is never reached and the run exits with a signal status instead of 0, which confuses any wrapper checking exit codes.
  4. Only AccessDenied limits the blast radius to same-user processes — which in practice is everything that matters on a shared workstation or a multi-run server.

Impact

Observed during batch reproduction (running multiple ideas in parallel on one machine, one launch_scientist_bfts.py per idea): the first launch to reach cleanup SIGTERMed the sibling launches and their experiment workers, aborting them mid-tree-search with no error of their own. Also observed launches terminating themselves via item 3, producing non-zero exit statuses for otherwise successful runs. We had to neutralize this block to run any parallel campaign.

Repro sketch

  1. On one machine, start two launches with different --idea_idx (or any second long-running Python process).
  2. Let the first reach the cleanup phase (e.g. a small/fast idea, or --skip_writeup --skip_review).
  3. Observe the second run (and any unrelated user Python process) receive SIGTERM; observe the first run's own exit status is a signal death rather than 0.

Suggested fix (minimal)

Delete the keyword sweep (lines 347–359). The preceding child-tree termination already handles the run's own processes, including recursive descendants.

If orphan cleanup beyond the child tree is genuinely needed (e.g. double-forked experiment processes), make it precise rather than keyword-based:

  • launch experiment workers with start_new_session=True and terminate the process group (os.killpg) on exit; or
  • record spawned PIDs at creation time and kill exactly those.

Either variant keeps cleanup scoped to processes the run actually created.

Source: SakanaAI/AI-Scientist-v2