Reference

Exit codes

What makes a jscpd run exit with 0, 1, 2 or a code of your own, and which flag controls each case.

A scan that finds clones exits 0: finding duplication is the normal result, not a failure. The exit code changes only when you ask for a gate or when the run itself could not do its job. Pre-commit hooks and CI systems read this code, so it is what turns a scan into a build step.

CodeWhenControlled by
0The run finished and no gate below tripped
1Total duplication is above --threshold (strictly greater: 50.0 % with --threshold 50 passes)--threshold <PERCENT>, config threshold
N (1 without a number)At least one clone was found--exit-code [N], config exitCode
1More than N clones are new against the baseline (N is 0 without a number)--fail-on-new-clones [N] with --baseline or --baseline-from-ref
1The scan analyzed no file: the paths exist but nothing matched --format, --ignore and --pattern, or every file was below --min-tokens--fail-on-empty, config failOnEmpty (5.2.1+)
1A format name that jscpd --list does not know, a scan path that does not exist, or a reporter that could not write its fileAlways, since 5.2.1; before that these cases wrote an empty report and exited 0
2The command line itself is wrong: an unknown flag or a value of the wrong typeThe argument parser

Reports are written before the gates run, so a failing job still leaves its JSON, HTML or SARIF file in --output.

Examples

Terminal
jscpd . --threshold 3            # exit 1 when duplication > 3 %
jscpd . --exit-code              # exit 1 when any clone is found
jscpd . --exit-code 3            # the same, with code 3
jscpd . --baseline .jscpd-baseline.json --fail-on-new-clones   # exit 1 on a clone that is not in the baseline
jscpd . --fail-on-empty          # exit 1 when nothing was analyzed
Terminal
jscpd fixtures/fail-on-empty-demo/code --format nosuchlang
echo $?
Error: --format: 'nosuchlang' is not a supported format (run with --list to see supported formats)
1

In CI

GitHub Actions and GitLab CI fail a step on any non-zero code, so --threshold or --fail-on-new-clones is all a gate needs. Two things hide the code: a shell pipe (jscpd . | tee log exits with tee's code unless set -o pipefail is on) and || true. The CI guide has the workflows.

See also