All AEM as a Cloud Service skills: component development, Workflow model design, development, triggering, launchers, debugging, and triaging, Dispatcher config authoring, advisory, incident response, performance tuning, and security hardening, Rapid Development Environment (RDE) deployment, log inspection, snapshots, and troubleshooting via `aio aem rde`, Jackrabbit Oak query/index tuning (property, Lucene index definitions), and extracting/inventorying JCR queries (XPath, SQL2, QueryBuilder) across a codebase.
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Fixes for the AEM Cloud SDK HTL lint warning "data-sly-test: redundant constant value comparison".
Rule: In HTL, data-sly-test should always receive a variable or expression that evaluates to boolean — never a raw string literal, raw true/false, or a number directly.
When the user pastes HTL lint warnings or asks to fix data-sly-test issues:
true/false, path string, number, split ${} || ${}) — see patterns below..html files.When the user wants to find and fix redundant data-sly-test issues but has no build log yet, run a heuristic scan on HTL templates, then fix hits using the patterns below.
Limits: Grep is not the HTL compiler. It can miss issues (multiline attributes, unusual quoting) and false-positive on expressions that are fine. After edits, mvn … generate-sources (or the Cloud Manager build) is still the authoritative check.
Scope: Prefer ui.apps/**/jcr_root/**/*.html and any other content packages that ship component HTL.
From the repository root, use ripgrep (rg):
| Pattern class | What to search | Example rg (run from repo root) |
|---|---|---|
| Boolean literal | == true, == false, != true, != false inside data-sly-test | `rg -n 'data-sly-test="[^"]==\s(true |
Raw /apps/… string as test | HTL string literal starting with /apps/ inside the attribute (common anti-pattern) | rg -n "data-sly-test=.*'/apps/" --glob '*.html' ui.apps (then confirm it is a useless string-as-test, not a legitimate comparison) |
Split || / && across ${} | Literal `} | |
| Numeric literal comparison | == <digits> inside a data-sly-test line (review each hit) | rg -n 'data-sly-test="[^"]*==\s*[0-9]+\s*}' --glob '*.html' ui.apps |
Agent workflow:
rg lines above (adjust ui.apps to the user's module paths if different).data-sly-test problem per the patterns below (skip unrelated == 1 in other attributes if any).== true / == false)The warning value is true or false. The HTL expression compares a variable against a boolean literal.
<div data-sly-test="${someVar == true}">visible when someVar is truthy</div>
<div data-sly-test="${someVar == false}">visible when someVar is falsy</div><div data-sly-test="${someVar}">visible when someVar is truthy</div>
<div data-sly-test="${!someVar}">visible when someVar is falsy</div>== true → remove the comparison; HTL treats the variable as boolean by default== false → negate with !data-sly-test.varName, preserve the variable name:<!-- Before -->
<div data-sly-test.isActive="${model.active == true}">
<!-- After -->
<div data-sly-test.isActive="${model.active}">!= true / != false<!-- != true is the same as == false -->
<div data-sly-test="${someVar != true}"> → <div data-sly-test="${!someVar}">
<!-- != false is the same as == true -->
<div data-sly-test="${someVar != false}"> → <div data-sly-test="${someVar}">The warning value is a string like /apps/bcbsmgeneral/components/content/container. A raw string literal inside data-sly-test is always truthy (non-empty string), so the condition is meaningless.
The author almost always meant to compare a variable against that string. Common cases:
| Intent | Variable to compare |
|---|---|
| Check current resource type | resource.resourceType |
| Check a child resource type | childResource.resourceType |
| Check a property value | properties.someProperty |
Check a data-sly-resource path | a variable holding the resource type |
<!-- Always truthy — the string itself is the test -->
<div data-sly-test="${'/apps/bcbsmgeneral/components/content/container'}">
...
</div>Determine what variable should be compared. The most common fix:
<!-- Compare resource type (strip /apps/ prefix for sling:resourceType) -->
<div data-sly-test="${resource.resourceType == 'bcbsmgeneral/components/content/container'}">
...
</div>Or if the path was being passed to data-sly-resource:
<!-- The test was guarding a data-sly-resource include -->
<sly data-sly-set.containerType="${'bcbsmgeneral/components/content/container'}"/>
<div data-sly-test="${containerType}"
data-sly-resource="${resource @ resourceType=containerType}">
</div>data-sly-test value/apps/ prefix when comparing against resource.resourceType (Sling stores relative resource types)data-sly-set and add a TODO comment:<!-- TODO: verify the correct variable for this comparison -->
<sly data-sly-set.expectedType="${'bcbsmgeneral/components/content/container'}"/>
<div data-sly-test="${resource.resourceType == expectedType}">When iterating child resources (e.g. data-sly-list), the comparison often belongs on the child:
<!-- Before (warns — raw path string) -->
<sly data-sly-list.child="${resource.children}">
<div data-sly-test="${'/apps/bcbsmgeneral/components/content/container'}">
<sly data-sly-resource="${child}"/>
</div>
</sly>
<!-- After -->
<sly data-sly-list.child="${resource.children}">
<div data-sly-test="${child.resourceType == 'bcbsmgeneral/components/content/container'}">
<sly data-sly-resource="${child}"/>
</div>
</sly>The warning value is a number like 1 or 2. HTL's linter flags numeric literals in comparisons even when the logic is correct.
<div data-sly-test="${properties.columnCount == 1}">one column</div>
<div data-sly-test="${properties.columnCount == 2}">two columns</div>Extract the comparison into a data-sly-set variable:
<sly data-sly-set.isOneColumn="${properties.columnCount == 1}"/>
<sly data-sly-set.isTwoColumn="${properties.columnCount == 2}"/>
<div data-sly-test="${isOneColumn}">one column</div>
<div data-sly-test="${isTwoColumn}">two columns</div>data-sly-set so data-sly-test only sees a boolean variableisOneColumn, isTypeTwo, etc.)data-sly-set on a <sly> element before the element that uses data-sly-testdata-sly-set declarations together at the topFor complex switch logic, expose a method from the model:
public boolean isOneColumn() {
return getColumnCount() == 1;
}<div data-sly-test="${model.oneColumn}">one column</div>The warning value is something like ${properties.videoUrl} || ${properties.videoUrl1}. HTL does not support || or && operators across separate ${} expression blocks.
When you write:
<div data-sly-test="${properties.videoUrl} || ${properties.videoUrl1}">HTL evaluates ${properties.videoUrl} as one expression and treats the literal string || and ${properties.videoUrl1} as separate tokens. The result is unpredictable and always flagged.
<div data-sly-test="${properties.videoUrl} || ${properties.videoUrl1}">
video content
</div>Combine into a single ${} block:
<sly data-sly-set.hasVideo="${properties.videoUrl || properties.videoUrl1}"/>
<div data-sly-test="${hasVideo}">
video content
</div>Or inline if the expression is short:
<div data-sly-test="${properties.videoUrl || properties.videoUrl1}">
video content
</div>||, &&, ternary ? :) must be inside a single ${} blockdata-sly-set for readability&&:<!-- BAD -->
<div data-sly-test="${properties.a} && ${properties.b}">
<!-- GOOD -->
<div data-sly-test="${properties.a && properties.b}">After fixing all warnings in a file:
mvn clean install and confirm no redundant constant value comparison warnings remain for this filedata-sly-test.varName was changed, all downstream ${varName} references still workdata-sly-set — every data-sly-set variable is used by at least one data-sly-testSome warnings require human judgment:
resource.resourceType or properties.* candidate)data-sly-include or data-sly-template — the scope of variables may differFlag these to the user with a TODO comment and move on.
.tessl-plugin
skills
aem-rde
aem-workflow
code-assessment
content-distribution
create-component
assets
references
dispatcher
incident-response
references
dispatcher-foundation
performance-tuning
references
dispatcher-foundation
security-hardening
references
dispatcher-foundation
technical-advisory
references
dispatcher-foundation
workflow-orchestrator
references
dispatcher-foundation
ensure-agents-md
references
migration
references
dispatcher
legacy-ui
template-modernization
validation
scripts
dispatcher-tool
validate-migration