{"record":{"id":"c91aa86541fd0475","repo":"kubernetes/kubernetes","slug":"variable-composition-is-not-allowed","errorCode":null,"errorMessage":"variable composition is not allowed","messagePattern":"variable composition is not allowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/admissionregistration/validation/validation.go","lineNumber":1028,"sourceCode":"\t} else {\n\t\tif compiler, ok := compiler.(*plugincel.CompositedCompiler); ok {\n\t\t\tenvType := environment.NewExpressions\n\t\t\tif opts.preexistingExpressions.validationExpressions.Has(v.Expression) {\n\t\t\t\tenvType = environment.StoredExpressions\n\t\t\t}\n\t\t\tvariable := &validatingadmissionpolicy.Variable{\n\t\t\t\tName:       v.Name,\n\t\t\t\tExpression: v.Expression,\n\t\t\t}\n\t\t\tresult := compiler.CompileAndStoreVariable(variable, plugincel.OptionalVariableDeclarations{\n\t\t\t\tHasParams:     paramKind != nil,\n\t\t\t\tHasAuthorizer: true,\n\t\t\t}, envType)\n\t\t\tif result.Error != nil {\n\t\t\t\tallErrors = append(allErrors, convertCELErrorToValidationError(fldPath.Child(\"expression\"), variable, result.Error))\n\t\t\t}\n\t\t} else {\n\t\t\tallErrors = append(allErrors, field.InternalError(fldPath, fmt.Errorf(\"variable composition is not allowed\")))\n\t\t}\n\t}\n\treturn allErrors\n}\n\nfunc validateValidation(compiler plugincel.Compiler, v *admissionregistration.Validation, paramKind *admissionregistration.ParamKind, opts validationOptions, fldPath *field.Path) field.ErrorList {\n\tvar allErrors field.ErrorList\n\ttrimmedExpression := strings.TrimSpace(v.Expression)\n\ttrimmedMsg := strings.TrimSpace(v.Message)\n\ttrimmedMessageExpression := strings.TrimSpace(v.MessageExpression)\n\tif len(trimmedExpression) == 0 {\n\t\tallErrors = append(allErrors, field.Required(fldPath.Child(\"expression\"), \"expression is not specified\"))\n\t} else {\n\t\tallErrors = append(allErrors, validateValidationExpression(compiler, v.Expression, paramKind != nil, opts, fldPath.Child(\"expression\"))...)\n\t}\n\tif len(v.MessageExpression) > 0 && len(trimmedMessageExpression) == 0 {\n\t\tallErrors = append(allErrors, field.Invalid(fldPath.Child(\"messageExpression\"), v.MessageExpression, \"must be non-empty if specified\"))\n\t} else if len(trimmedMessageExpression) != 0 {","sourceCodeStart":1010,"sourceCodeEnd":1046,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/94c136764292cc5fac976c0de6587daaea56410f/pkg/apis/admissionregistration/validation/validation.go#L1010-L1046","documentation":"Returned as a field.InternalError when validating a ValidatingAdmissionPolicy variable definition and the CEL compiler passed to the validator is not a *plugincel.CompositedCompiler (i.e. it does not support variable composition / expression compilation and storage). This is an internal/server-side configuration problem, not a user-facing CEL expression error.","triggerScenarios":"A ValidatingAdmissionPolicy that declares one or more variables (spec.variables) is submitted to an API server whose admission CEL compiler is a plain compiler that lacks the CompositedCompiler type. The validator checks the compiler type at runtime and fails because variable composition requires storing compiled expressions.","commonSituations":"Running a custom API server build that wires a minimal CEL compiler without the composition plugin; version skew where the API server binary predates variable support but the CRD/policy schema accepts variables; test harness using a mock compiler.","solutions":["Upgrade the API server to a version that registers the CompositedCompiler for admission policy validation.","If running a custom apiserver, ensure the CEL environment factory returns a *plugincel.CompositedCompiler (see plugincel.NewCompositedCompiler).","If you cannot upgrade, remove spec.variables from the ValidatingAdmissionPolicy and inline the expressions."],"exampleFix":"// before — custom apiserver wires a plain compiler\ncompiler := cel.NewCompiler(env)\n\n// after — use the composited compiler that supports variable composition\ncompiler := plugincel.NewCompositedCompiler(env, optionalDeclarations)","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the API server registers plugincel.NewCompositedCompiler for admission validation.","Do not deploy ValidatingAdmissionPolicies with spec.variables on API servers that predate variable support.","Run a conformance/compatibility check: submit a trivial policy with one variable against the target server."],"tags":["admissionregistration","cel","internal-error","vap","compiler"],"backgroundTag":null,"analyzedSha":"94c136764292cc5fac976c0de6587daaea56410f","analyzedAt":"2026-08-08T23:58:27.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}