When things break
A red run in the Actions tab tells you which thing broke without you opening the log, because the exit codes are distinct.
| Code | Meaning | What was changed |
|---|---|---|
0 | Success, including "nothing tagged". | Whatever the run decided. |
1 | Configuration error, caught before IBM is contacted. | Nothing. |
2 | IBM could not be reached. | Nothing. |
3 | A required notification channel failed. | Nothing. |
4 | A job's tags can never be written. The log names it. | Everything else in the run. |
The guarantee behind codes 2 and 3
When Qoffee cannot reach IBM, or cannot deliver a message to a required channel, it changes nothing at all. Every tag is left exactly as it was and the same news is reported again on the next run.
This is the property the whole tool rests on. A job is never untagged unless the notification about it was confirmed delivered. A transient network problem therefore costs you a red run and nothing else, and self corrects fifteen minutes later.
Code 4 is the one that needs you
Everything else retries on its own. Code 4 does not, and cannot.
It means a tag write will never succeed no matter how many times it is tried. In practice this is always the same thing: the job already carries five tags of your own, and IBM allows five, so there is no room for Qoffee's state tag.
Since there is no database, Qoffee cannot record that it gave up. Left as a generic error it would be swallowed and retried forever, which reaches you as endless duplicate notifications on a run that looks green. So it is surfaced instead: the run goes red, the log names the job, and it stays that way until you act.
Remove one tag from that job, or remove qoffee from it, and the next run proceeds normally.
The other jobs in the same run are unaffected. One job's tag write failing does not abandon the rest.
Reading the log
Before anything is applied, the whole plan is written to the log, one line per job, each with the reason.
plan: notify=True actions=3
setstate job#3beed3 - state changed to RUNNING
resolve job#a71fe4 - completed successfully
leave job#c02b8a - failure held; batch still active
When something behaves in a way you did not expect, "why is this job still tracked" is the question, and that is where the answer is. The three verbs are the only three things Qoffee can decide to do.
| Verb | Meaning |
|---|---|
setstate | Record a new status on the job. Applied only after a confirmed send. |
resolve | Stop tracking this job. Applied only after a confirmed send. |
leave | Do nothing. Never touches a tag. |
Job IDs appear as short hashes because the log on a public repository is world readable. The same job produces the same hash within a run, so the lines stay correlatable. See what the public log shows.
Exit codes are defined at the top of qoffee/core/engine.py and documented again in qoffee/cli.py.