Start a project
WorkBlogResourcesAboutContact

Blog/Failures and fixes

I Stopped the Image Batch but It Kept Spending Credits

Canceling a background batch on Windows left its child processes alive, generating PNGs and spending credits.

By Jeff Zambrano··5 min read

I Stopped the Image Batch but It Kept Spending Credits

New PNGs kept appearing after I stopped the background batch.

The credit balance also kept falling.

The stop command had reported that the task was canceled, so the batch looked dead from the interface I had used to launch it. On Windows, that result did not mean the complete process tree had stopped.

Two bash.exe processes were still running the generation batch. One belonged to a GPT run I had “stopped” half an hour earlier. The other belonged to a nano run. Below them, the generation chain was still alive:

sh.exe → node.exe → hf.exe

The wrapper had stopped. Its children had not.

Canceling the parent was not enough

The batch ran in the background through Git Bash on Windows. Inside it was a loop that continued reading work and launching Higgsfield generation commands.

Stopping the background task killed the wrapper associated with that task. The kill did not propagate through the child process tree. The child bash.exe continued as an orphan, and its while read loop kept moving through the batch.

That is why the interface and the output directory told different stories.

The interface said the task had stopped. The directory kept receiving images because the actual generation process still had living descendants. Higgsfield kept receiving requests, so credits continued to be spent.

A process name alone was not enough to identify the right tree. Windows can have several shell, Node, or command-line processes open at the same time. Killing every process with a common executable name would be imprecise.

The useful identifier was the command line.

I inspected the live processes by command line

The verified inspection used Win32_Process:

Get-CimInstance Win32_Process |
  Where-Object { $_.CommandLine -match 'generate-faces|higgsfield' }

This exposed the processes whose command lines contained the batch or Higgsfield generation terms.

That inspection found the two surviving bash.exe processes as well as the child chain. It did not depend on the background task interface remembering them. It asked Windows what was still running.

I reviewed the matches before stopping anything. The command line connected each PID to the paid generation work. That is safer and more useful than looking for bash.exe in isolation, because bash.exe only tells me which executable is running. It does not tell me what that executable is doing.

After identifying the correct PIDs, I used Stop-Process -Force on each process in the generation tree.

The important part was not the force option by itself. It was the PID selection that came first. Each target had been tied to the batch through its command line.

The second check mattered as much as the stop

I did not treat the stop command as proof that the work had ended. That assumption had already failed once.

After stopping the matched PIDs, I checked the process list again with ps aux | grep, searching for the same batch and Higgsfield terms. The batch was only considered stopped when none of the relevant processes remained.

That final check closes the gap between issuing a kill and confirming its effect.

For a normal local batch, an orphaned shell may be an annoyance. For a paid generation batch, it is an active expense. Every iteration can create another job even though I believe I have canceled the run.

The output folder provides another warning. If new files continue appearing, the batch is not stopped, regardless of what the wrapper reports. The credit balance provides the same warning from the billing side.

Neither should be the primary control, though. By the time another image appears or the balance changes, another request may already have been sent. The process tree is the direct check.

I changed what the batch records

Paid batch scripts should log their PID.

That gives me a precise starting point when I need to stop a run. I can identify the recorded process, inspect its descendants, and confirm which command lines belong to the batch.

The PID does not remove the need to verify children on Windows. It makes the verification faster and reduces ambiguity when several shells are active.

The complete stopping procedure is now part of running the batch, not emergency cleanup after it:

Start the batch and record its PID. When canceling, stop the intended task. Inspect Win32_Process for matching command lines. Stop every confirmed process in the generation tree. Inspect again until no relevant process remains.

Only then is the batch stopped.

The rule I use now

A successful cancellation message is not evidence that a paid Windows batch has ended.

The evidence is an empty process search for that batch and its generation command. If bash.exe, sh.exe, node.exe, or hf.exe remains attached to the matching command line, the work can continue.

If you run paid AI batches on Windows, add PID logging today. The next time you cancel one, inspect Win32_Process by command line and verify the entire tree is gone before you trust the stop.


Every fix in this article was paid for with a mistake first. Better on my film than on your brand.

ShareXLinkedInWhatsApp
Jeff Zambrano

Jeff Zambrano is a Madrid-based AI film director. His debut, Borrowed Wounds, reached the Top 50 of the Higgsfield Global Film Festival out of 6,700 films. He writes these notes from his own productions.

WhatsApp