Pipeline - Build failed due to MissingPropertyException: No such property: env

Article ID:360050134172
1 minute readKnowledge base

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

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)