Issue
Pipeline builds fail with the exception that looks like following:
groovy.lang.MissingPropertyException: No such property: env for class: groovy.lang.Binding at groovy.lang.Binding.getVariable(Binding.java:63) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:270) at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:291) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:354) at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:291) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:295) at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$1.callStatic(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:230) at Script5.<init>(Script5.groovy:10) ... Finished: FAILURE
Environment
-
CloudBees CI (CloudBees Core) on modern cloud platforms - Managed controller
-
CloudBees CI (CloudBees Core) on traditional platforms - Client controller
-
CloudBees Jenkins Enterprise - Managed controller
Resolution
Inspect recent changes to the Pipeline Definition looking for the following pattern:
// a.groovy import groovy.transform.Field @Field def LOADED_BUILD_NUMBER = "${env.BUILD_NUMBER}" return this
// Jenkinsfile node() { checkout scm def a = load('a.groovy') echo("${env.BUILD_NUMBER}") echo("${a.LOADED_BUILD_NUMBER}") }
If it is the case you are affected by the known issue [JENKINS-63384] load step fails to bind "complex" @Field defined variables. At the time of the writing (2 Oct 2020) there is no fix for it.
Workaround
Rewriting the load
-ed Groovy script to avoid using of @Field
initialized with values global variables. For example above script can be re-written:
// a.groovy class BuildValueObject { def LOADED_BUILD_NUMBER BuildValueObject(script) { this.LOADED_BUILD_NUMBER = "${script.env.BUILD_NUMBER}" } } return new BuildValueObject(this)
This article is part of our Knowledge Base and is provided for guidance-based purposes only. The solutions or workarounds described here are not officially supported by CloudBees and may not be applicable in all environments. Use at your own discretion, and test changes in a safe environment before applying them to production systems.