Jenkins Pipeline uses a library called Groovy CPS to run Pipeline scripts.
While Pipeline uses the Groovy parser and compiler, unlike a regular Groovy environment it runs most of the program inside a special interpreter.
This uses a continuation-passing style (CPS) transform to turn your code into a version that can save its current state to disk (a file called
program.dat
  inside your build directory) and continue running even after Jenkins has restarted.
(You can get some more technical background on the Pipeline: Groovy plugin page and the library page.)
While the CPS transform is usually transparent to users, there are limitations to what Groovy language constructs can be supported, and in some circumstances it can lead to counterintuitive behavior.
JENKINS-31314Â makes the runtime try to detect the most common mistake: calling CPS-transformed code from non-CPS-transformed code.
The following kinds of things are CPS-transformed:
-
Almost all of the Pipeline script you write (including in libraries)
-
Most Pipeline steps, including all those which take a block
The following kinds of things are
not
 CPS-transformed:
-
Compiled Java bytecode, including
-
Constructor bodies in your Pipeline script
-
Any method in your Pipeline script marked with theÂ
@NonCPS
 annotation
-
A few Pipeline steps which take no block and act instantaneously, such asÂ
echo
 orÂ
properties
CPS-transformed code may call non-CPS-transformed code or other CPS-transformed code, and non-CPS-transformed code may call other non-CPS-transformed code, but non-CPS-transformed code
may not
call CPS-transformed code.
If you try to call CPS-transformed code from non-CPS-transformed code, the CPS interpreter is unable to operate correctly, resulting in incorrect and often confusing results.