AutoSys Job Dependencies and Conditions — Controlling Job Chains
success(), failure(), done(), notrunning(), and complex AND/OR conditions.- AutoSys provides four condition types:
success(),failure(),done(), andnotrunning() - done() is the right choice for cleanup or notification jobs that must run regardless of the upstream job's outcome
- Conditions can reference jobs in other boxes or boxes themselves
- AutoSys conditions define when a job can start based on other jobs' statuses
- Four functions: success(), failure(), done(), notrunning()
- Combine with AND / OR and parentheses for complex rules
- Conditions evaluate after the referenced job finishes (or stops running for notrunning)
- Common failure: using success() for cleanup jobs — use done() instead
- In production, complex conditions with many AND/OR masks timing issues — test with autorep first
Quick Debug Cheat Sheet for AutoSys Conditions
Job won't start (pending with condition_unmet)
autorep -q <jobname> | grep -i conditionautorep -q <referenced_job> | grep -i statusJob runs but shouldn't have (early trigger)
autorep -q <jobname> | grep conditionCheck job log: autorep -q <jobname> -l0 | tail -20Cleanup job never fires after failure
autorep -q <cleanup_job> | grep conditionautorep -q <upstream_job> | grep statusProduction Incident
notrunning() to allow job_B to run if job_A was never started.failure() require the referenced job to have run at least once and terminated. INACTIVE jobs never produce a true evaluation.For jobs that must always run after a predecessor, even if the predecessor is skipped, use done() or notrunning() with an additional calendar check.Always verify referenced jobs are scheduled and not on hold. Use autorep -q job_A to check status before the batch window.Production Debug GuideSymptom → Action: Diagnose dependency failures fast
success() instead of done(). Cleanup jobs should always use done() so they fire regardless of upstream exit code.notrunning() evaluates to true as soon as the referenced job is not running, even if it hasn't started yet. Use success() or done() for sequential execution, not notrunning().Dependency management is AutoSys's superpower — the thing that justifies its cost over cron. The condition attribute lets you express exactly what must be true before a job can start. You can chain hundreds of jobs with precise dependency rules, and AutoSys handles the orchestration automatically.
This article covers all condition types, how to combine them, and the gotchas that cause dependency chains to break in production.
The four condition functions
AutoSys provides four functions for expressing job conditions:
- success(job): Triggers when the referenced job completes with exit code 0
- failure(job): Triggers when the referenced job completes with non-zero exit code
- done(job): Triggers when the referenced job completes, regardless of exit code
- notrunning(job): Triggers when the referenced job is not currently in RUNNING state
Each function takes the name of another job (or box) as argument. The condition is evaluated when the referenced job changes state. For , success(), and failure() the state change is completion/termination. For done() it's any transition out of RUNNING, including job start (from not-running to running also triggers, but that's not typical usage).notrunning()
/* success(job) — run after job_a completes successfully */ condition: success(job_a) /* failure(job) — run after job_a fails (error handling job) */ condition: failure(job_a) /* done(job) — run after job_a is done, regardless of success or failure */ condition: done(job_a) /* notrunning(job) — run when job_a is NOT currently running */ condition: notrunning(job_a) /* Combining conditions with AND */ condition: success(job_a) AND success(job_b) /* Combining with OR */ condition: success(job_a) OR success(job_b) /* Complex condition */ condition: success(job_a) AND (success(job_b) OR success(job_c))
success() for cleanup jobs.done() for cleanup, notification, or logging jobs.Cross-box dependencies
Conditions can reference jobs in other boxes or standalone jobs. This lets you build workflows that span multiple boxes.
When a condition references a job outside the current box, AutoSys uses global job name resolution. The referenced job must have a unique name across the entire AutoSys instance — if duplicates exist, the condition may resolve to the wrong job.
You cannot condition on a box name to wait for all children of that box. Instead, condition on the last child job of that box, or use done(box_name) which completes only when all children of that box have finished.
/* Job in reporting_box waits for a job in etl_box */ insert_job: generate_daily_report job_type: CMD box_name: reporting_box command: /scripts/daily_report.sh machine: report-server owner: batch condition: success(etl_load_job) /* etl_load_job is in etl_box */
done() on the box job itself, which completes when all its children are done.The done() condition and why it matters
done() is often overlooked but very useful. It lets a job run after another job completes regardless of whether that job succeeded or failed. This is perfect for cleanup or notification jobs that should always run.
- Cleanup temp files after a job completes
- Send status email with success/failure info
- Update a monitoring system with job execution results
Because done() triggers after any termination — including kill or timeout — it ensures your post-processing runs reliably.
/* Cleanup job: runs whether or not main job succeeded */ insert_job: cleanup_temp_files job_type: CMD command: /scripts/cleanup.sh machine: server01 owner: batch condition: done(main_etl_job) /* runs regardless of main_etl_job outcome */ /* Notification job: always sends status email */ insert_job: send_batch_status_email job_type: CMD command: "/scripts/notify.sh --job main_etl_job" machine: server01 owner: batch condition: done(main_etl_job)
success() and failure() on separate branches.success() or failure()done() — cleanup, notification, monitoringnotrunning() with caution, or force-run the upstream job.notrunning(): preventing concurrent execution
The condition triggers when the referenced job is not in RUNNING state. This is useful for throttling or serialising jobs that share a resource.notrunning()
Important caveat: evaluates true if the referenced job has never run (INACTIVE status). That means if you write notrunning()condition: notrunning(app_job) and app_job hasn't been scheduled yet, the condition is immediately true — the dependent job will start right away, likely not what you intended.
To prevent concurrent runs of the same job, use condition: notrunning(app_job) where app_job is the same job. AutoSys supports self-referencing conditions for this purpose. When used on the same job, the condition is met only after the previous instance finishes.
/* Report generator: only one instance at a time */ insert_job: daily_report job_type: CMD command: /scripts/report.sh machine: server01 owner: batch condition: notrunning(daily_report) /* self-reference prevents overlap */ /* Resource-dependent job: wait until resource job finishes */ insert_job: process_batch job_type: CMD command: /scripts/process.sh machine: server02 owner: batch condition: notrunning(resource_cleanup) /* ensures cleanup is not running */
notrunning() returns true. This can cause dependent jobs to start unexpectedly. Always verify the referenced job's schedule and status.notrunning() is the standard pattern for job serialization.notrunning() with a time condition (start_times) or ensure the referenced job has run at least once.success() or done().Complex conditions with AND, OR, and parentheses
You can build complex dependency logic by combining conditions with AND and OR operators, and using parentheses to control evaluation order. AutoSys evaluates conditions from left to right, respecting parentheses. There's no NOT operator.
Example: You need a job to run if either Job A and Job B both succeeded, OR Job C succeeded. The condition would be:
condition: (success(job_a) AND success(job_b)) OR success(job_c)
Without parentheses, AND has higher precedence than OR, so: condition: success(job_a) AND success(job_b) OR success(job_c) is equivalent to: condition: (success(job_a) AND success(job_b)) OR success(job_c)
However, it's safer to always use explicit parentheses for readability and to avoid future misinterpretation.
Complex conditions are powerful but can lead to hard-to-debug behaviours. If you have many conditions, consider breaking the logic into intermediate box jobs to simplify each condition.
/* Real-world example: Run final aggregation if (ETL success AND validation success) OR manual override flag */ insert_job: final_aggregation job_type: CMD box_name: reporting_box command: /scripts/aggregate.sh machine: batch-server owner: batch condition: (success(run_etl) AND success(validate_data)) OR success(manual_override) /* Use intermediate box to simplify */ insert_job: etl_and_validation_box job_type: BOX insert_job: run_etl job_type: CMD box_name: etl_and_validation_box command: /scripts/etl.sh insert_job: validate_data job_type: CMD box_name: etl_and_validation_box command: /scripts/validate.sh condition: success(run_etl) /* Now final job condition becomes simpler */ insert_job: final_aggregation job_type: CMD command: /scripts/aggregate.sh condition: success(etl_and_validation_box) OR success(manual_override)
| Condition | Triggers when... | Common use case |
|---|---|---|
| success(job) | Job completed with exit code 0 | Normal sequential dependency |
| failure(job) | Job completed with non-zero exit code | Error handling / failover job |
| done(job) | Job completed (either success or failure) | Cleanup / notification jobs |
| notrunning(job) | Job is not currently RUNNING | Preventing concurrent execution |
🎯 Key Takeaways
- AutoSys provides four condition types:
success(),failure(),done(), andnotrunning() - done() is the right choice for cleanup or notification jobs that must run regardless of the upstream job's outcome
- Conditions can reference jobs in other boxes or boxes themselves
- AND/OR logic lets you build complex dependency rules — test them carefully before deploying to production
- Circular dependencies are not detected at definition time; manually review chains for loops
- notrunning() is for concurrency control, not sequential dependency — it evaluates true if the referenced job never ran
⚠ Common Mistakes to Avoid
Interview Questions on This Topic
- QWhat is the difference between
success()anddone()conditions in AutoSys?JuniorReveal - QWhat does the condition
failure()do?JuniorReveal - QCan an AutoSys job condition reference jobs in a different box?Mid-levelReveal
- QWhat happens if you have a circular dependency in AutoSys conditions?SeniorReveal
- QWhat condition would you use for a cleanup job that must run whether or not the main job succeeded?JuniorReveal
- QHow does the
notrunning()condition behave if the referenced job has never run?SeniorReveal
Frequently Asked Questions
What conditions can I use in AutoSys?
AutoSys provides four condition functions: success(job) — job completed successfully; failure(job) — job failed; done(job) — job completed regardless of outcome; notrunning(job) — job is not currently running. You can combine these with AND and OR operators.
What is the done() condition in AutoSys?
done() triggers when a job has completed, whether it succeeded or failed. It's commonly used for cleanup jobs, status notification jobs, or any job that should always run after an upstream job finishes, regardless of outcome.
Can AutoSys job conditions span multiple boxes?
Yes. The condition attribute can reference any job in the AutoSys instance, regardless of which box it belongs to. The referenced job name must be unique across the instance.
What happens if I create a circular dependency in AutoSys?
AutoSys won't detect circular dependencies at job definition time. The jobs will deadlock — Job A waits for B, Job B waits for A, and neither ever starts. You need to carefully review dependency chains to prevent this.
How do I make a job run after any one of several jobs succeeds?
Use OR in your condition: condition: success(job_a) OR success(job_b). The job starts as soon as either condition becomes true.
What is the difference between notrunning() and success()?
notrunning() checks if a job is currently not running (state is not RUNNING). It evaluates true if the job never ran, finished, or was killed. success() only evaluates true after the job has completed with exit code 0. Use success() for sequential chaining, notrunning() for serialization.
Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.