Evaluability Rules (EVL)
Evaluability rules flag TypeScript patterns that the chant evaluator cannot statically resolve. All evaluability rules have severity error.
EVL001: Non-Literal Expression
Section titled “EVL001: Non-Literal Expression”Resource property values must be statically evaluable. Function calls, method calls, and other dynamic expressions are not allowed.
// ❌ Triggers EVL001export const bucket = new _.Resource({ bucketName: getName(), tags: Object.assign({}, baseTags),});// ✅ Fixedconst name = "my-data-bucket";const tags = { ...baseTags, env: "prod" };
export const bucket = new _.Resource({ bucketName: name, tags: tags,});EVL002: Control Flow Wrapping Resources
Section titled “EVL002: Control Flow Wrapping Resources”Resource instantiation cannot appear inside control flow blocks (if, for, while, switch, try). Resources must be declared at the top level.
// ❌ Triggers EVL002if (env === "prod") { export const bucket = new _.Resource({ bucketName: "prod-data", });}// ✅ Fixedexport const bucket = new _.Resource({ bucketName: "my-data",});EVL003: Dynamic Property Access
Section titled “EVL003: Dynamic Property Access”Computed property access with a non-literal key cannot be evaluated statically.
// ❌ Triggers EVL003const region = config[key];// ✅ Fixedconst region = config["production"];EVL004: Spread From Non-Const Source
Section titled “EVL004: Spread From Non-Const Source”The spread operator requires the source to be traceable to a const declaration.
// ❌ Triggers EVL004export const bucket = new _.Resource({ ...getDefaults(),});// ✅ Fixedconst defaults = { versioning: true, encryption: "AES256" };
export const bucket = new _.Resource({ ...defaults,});EVL005: Block Body in resource() Callback
Section titled “EVL005: Block Body in resource() Callback”Callbacks passed to resource() must use expression body syntax. Block bodies with return statements cannot be statically evaluated.
// ❌ Triggers EVL005resource(_.Resource, (props) => { const name = props.name + "-data"; return { bucketName: name };});// ✅ Fixed — use expression bodyresource(_.Resource, (props) => ({ bucketName: props.name + "-data",}));EVL007: Invalid Siblings Access
Section titled “EVL007: Invalid Siblings Access”In composite resources, accessing siblings.key.attr where key does not exist in the resource map is an error.
// ❌ Triggers EVL007resource(_.ServiceType, (props, siblings) => ({ role: siblings.typo.arn,}));// ✅ Fixedresource(_.ServiceType, (props, siblings) => ({ role: siblings.executionRole.arn,}));