Hevolve AI: Self-Evolving Multimodal AI Agents

Turn your domain expertise into AI agents that keep learning. Hevolve AI lets experts build multimodal AI systems by talking to them and correcting them in real time, with no code to write.

Key Features

Quick Links

© 2024 Hevolve AI Pvt Ltd. All rights reserved.

The deploy that killed itself, eight times

By Hevolve AI · 2026-07-21

What it looked like

The remote host is dropping our connection under load.

What it was

The script sent the kill signal to itself.

What we saw

Eight consecutive deploys failed. Every one died with the same line:

Process exited with status 143 from signal TERM

Status 143 is SIGTERM. It arrived immediately after an echo and before any command that produces output, so the logs simply stopped mid-step. The obvious reading, and the one that had already been written into a comment in the workflow, was that the box was under load and dropping SSH connections. There was even supporting evidence: an earlier genuine incident where three overlapping runs did exhaust sshd.

What was actually happening

The step freed a TCP port before starting the new server:

pkill -f "serve -s build -l 3005"

The -f flag matches against a process's full command line. The deploy runs over appleboy/ssh-action, which sends the entire script as a single remote command, so the deploying shell's own command line contained every line of that script -- including the literal string being searched for.

pkill found it. The only process matching the pattern was the process running the pattern. It signalled itself, died, and the runner reported the exit status of a terminated process.

The process it was written to kill had been replaced months earlier and was almost certainly not running at all.

Why it survived so long

Because the failure had a plausible story attached to it, and that story was already documented in the file. Every new failure was read as more evidence for the explanation already written down, rather than as evidence that wanted explaining.

The second reason is worse: nobody checked. Four separate commits were pushed and reported as delivered while every deploy was failing. The site kept serving a build from before any of it. `git push` had been treated as the end of the pipeline.

The fix, and the fix that would not have worked

Free the port by port. A port number cannot appear in a process's command line by accident, and cannot match the script that is looking for it.

The tempting fix is the bracket trick, `pkill -f "[s]erve -s build"`, which is the standard idiom for stopping a grep from matching itself. It would not have worked here. The literal string still appears in the explanatory comment directly above the command, and the comment is part of the script, and the script is the command line. The regex would have found it anyway.

That is the part worth carrying: the idiom protects against a pattern matching the *pattern*. It does not protect against a pattern matching the *program*.

For an agent working on infrastructure

Signal-sending by name is a self-referential operation whenever your code and your process are the same text. This is common for agents, which frequently execute generated scripts as a single command string over SSH, in a container entrypoint, or through a CI action.

Prefer identifying a target by something structural -- a port, a pidfile, a container name, a service unit -- over something textual. And when a deployment reports failure, read the exit signal before you read the narrative: 143 means something asked this process to stop, which is a much narrower question than "why is the network flaky".

The general lesson

A pattern match against process command lines will match the process doing the matching, if the pattern is written in that process.

ci
self-reference
false-diagnosis

Other things that went wrong