Skip to content

Evaluability Rules (EVL)

Evaluability rules flag TypeScript patterns that the chant evaluator cannot statically resolve. All evaluability rules have severity error.


Resource property values must be statically evaluable. Function calls, method calls, and other dynamic expressions are not allowed.

// ❌ Triggers EVL001
export const bucket = new _.Resource({
bucketName: getName(),
tags: Object.assign({}, baseTags),
});
// ✅ Fixed
const name = "my-data-bucket";
const tags = { ...baseTags, env: "prod" };
export const bucket = new _.Resource({
bucketName: name,
tags: tags,
});

Resource instantiation cannot appear inside control flow blocks (if, for, while, switch, try). Resources must be declared at the top level.

// ❌ Triggers EVL002
if (env === "prod") {
export const bucket = new _.Resource({
bucketName: "prod-data",
});
}
// ✅ Fixed
export const bucket = new _.Resource({
bucketName: "my-data",
});

Computed property access with a non-literal key cannot be evaluated statically.

// ❌ Triggers EVL003
const region = config[key];
// ✅ Fixed
const region = config["production"];

The spread operator requires the source to be traceable to a const declaration.

// ❌ Triggers EVL004
export const bucket = new _.Resource({
...getDefaults(),
});
// ✅ Fixed
const defaults = { versioning: true, encryption: "AES256" };
export const bucket = new _.Resource({
...defaults,
});

Callbacks passed to resource() must use expression body syntax. Block bodies with return statements cannot be statically evaluated.

// ❌ Triggers EVL005
resource(_.Resource, (props) => {
const name = props.name + "-data";
return { bucketName: name };
});
// ✅ Fixed — use expression body
resource(_.Resource, (props) => ({
bucketName: props.name + "-data",
}));

In composite resources, accessing siblings.key.attr where key does not exist in the resource map is an error.

// ❌ Triggers EVL007
resource(_.ServiceType, (props, siblings) => ({
role: siblings.typo.arn,
}));
// ✅ Fixed
resource(_.ServiceType, (props, siblings) => ({
role: siblings.executionRole.arn,
}));