One child dies. Now what?
The default is to keep waiting, which is rarely what you want. These four options let a failed child fail the parent, be ignored, cancel its siblings, or let the parent run on whatever succeeded.
When a Child Fails
Section titled “When a Child Fails”By default a parent just keeps waiting for its remaining children. Four child options change what happens when a child fails terminally (no retries left):
| Option | Behavior |
|---|---|
failParentOnFailure | Parent immediately moves to failed, even if other children are still running |
removeDependencyOnFailure | The failed child is silently dropped from the parent’s dependencies; the parent proceeds as if it never existed |
ignoreDependencyOnFailure | Like the above, but the failure is recorded; the parent can read it via job.getIgnoredChildrenFailures() |
continueParentOnFailure | Parent is promoted to run immediately; it can inspect failures via job.getFailedChildrenValues() and cancel leftover children |
Choose at most one policy per child. The selected policy and any unresolved
failure record are durable: a broker restart cannot reset the child to default
behavior or put an already-released parent back into waiting-children.
A worked example with continueParentOnFailure, useful when the parent should decide how to handle partial failure:
await flow.add({ name: 'pipeline', queueName: 'main', data: {}, children: [ { name: 'step-a', queueName: 'workers', data: {}, opts: { continueParentOnFailure: true } }, { name: 'step-b', queueName: 'workers', data: {}, opts: { continueParentOnFailure: true } }, { name: 'step-c', queueName: 'workers', data: {} }, ],});
const worker = new Worker('main', async (job) => { const failed = await job.getFailedChildrenValues(); // { 'workers:job-abc': 'Error: step-a failed', ... }
if (Object.keys(failed).length > 0) { await job.removeUnprocessedChildren(); // cancel children still waiting return { status: 'partial', failedSteps: failed }; } return { status: 'complete' };}, { embedded: true });import { FlowProducer, Queue, Worker } from 'bunqueue-client';
const flow = new FlowProducer();const queue = new Queue('main');
await flow.add({ name: 'pipeline', queueName: 'main', data: {}, children: [ { name: 'step-a', queueName: 'workers', data: {}, opts: { continueParentOnFailure: true } }, { name: 'step-b', queueName: 'workers', data: {}, opts: { continueParentOnFailure: true } }, { name: 'step-c', queueName: 'workers', data: {} }, ],});
const worker = new Worker('main', async (job) => { const failed = await queue.getFailedChildrenValues(job.id); // { 'workers:job-abc': 'Error: step-a failed', ... }
if (Object.keys(failed).length > 0) { await queue.removeUnprocessedChildren(job.id); // cancel children still waiting return { status: 'partial', failedSteps: failed }; } return { status: 'complete' };});from bunqueue import FlowProducer, Queue, Worker
flow = FlowProducer()queue = Queue("main")
flow.add({ "name": "pipeline", "queueName": "main", "data": {}, "children": [ {"name": "step-a", "queueName": "workers", "data": {}, "opts": {"continue_parent_on_failure": True}}, {"name": "step-b", "queueName": "workers", "data": {}, "opts": {"continue_parent_on_failure": True}}, {"name": "step-c", "queueName": "workers", "data": {}}, ],})
def process(job): failed = queue.get_failed_children_values(job.id) # {"workers:job-abc": "Error: step-a failed", ...}
if failed: queue.remove_unprocessed_children(job.id) # cancel children still waiting return {"status": "partial", "failed_steps": failed} return {"status": "complete"}
Worker("main", process).run()And with ignoreDependencyOnFailure, when the parent should continue with partial data:
const worker = new Worker('reports', async (job) => { const ignored = await job.getIgnoredChildrenFailures(); // { 'workers:job-abc': 'Error: enrichment API timeout' } return { partial: Object.keys(ignored).length > 0 };}, { embedded: true });const queue = new Queue('reports');
const worker = new Worker('reports', async (job) => { const ignored = await queue.getIgnoredChildrenFailures(job.id); // { 'workers:job-abc': 'Error: enrichment API timeout' } return { partial: Object.keys(ignored).length > 0 };});queue = Queue("reports")
def process(job): ignored = queue.get_ignored_children_failures(job.id) # {"workers:job-abc": "Error: enrichment API timeout"} return {"partial": bool(ignored)}
Worker("reports", process).run()All four failure-propagation options are ordinary job options and reach the wire in every SDK. The reading helpers (getFailedChildrenValues, getIgnoredChildrenFailures, removeUnprocessedChildren) are currently available in the Bun package, the TypeScript SDK and the Python SDK (on Queue, taking the job id).
Where to go next
Section titled “Where to go next”| Flow Producer | Your first parent/child graph, and what is guaranteed |
| Flow Patterns | Chains, fan-in, trees, reading child results, options |
| Flow Producer Reference | Every producer method, job helper and step field |