---
title: "HubL lint rules: all 28 checks codefmt catches"
url: https://codefmt.dev/hubl-lint-rules
sources:
  - https://codefmt.dev/hubl-lint-rules
licence: "© codefmt. Cite with attribution to https://codefmt.dev."
---

# HubL lint rules

codefmt's HubL linter runs **28 rules** on a single template, across six categories. Each is listed below with its rule id and severity; seven ship one-click safe fixes via the [Fix and Fix (unsafe) buttons](/hubl). Two further rules (tagged needs project context) only fire when codefmt has your whole theme, so they aren't part of the single-template count.

## correctness

Structural errors that stop a template from parsing or rendering.

* unclosed block`hubl/unclosed-block`error  
A {% for %}, {% if %}, {% block %}, or other opening tag has no matching {% end... %}.
* mismatched block`hubl/mismatched-block`error  
An opening and closing tag don't match, e.g. a {% for %} closed by {% endif %}.
* unclosed delimiter`hubl/unclosed-delimiter`error  
A {% %}, {{ }}, or {# #} is opened but never closed.
* unexpected closer`hubl/unexpected-closer`error  
A closing tag like {% endif %} appears with no matching opener.
* elif after else`hubl/elif-after-else`error  
An {% elif %} appears after {% else %}, where it can never run.
* unexpected mid-block tag`hubl/unexpected-mid`error  
A mid-block tag like {% else %} or {% elif %} appears outside the block it belongs to.
* unclosed raw block`hubl/raw-not-closed`error  
A {% raw %} block is missing its {% endraw %}.

## semantic

Code that parses but means the wrong thing in HubL, including js-mindset traps carried over from JavaScript.

* unknown filter`hubl/unknown-filter`info  
A filter name isn't a known HubL filter; codefmt suggests the closest match.
* wrong filter arity`hubl/filter-arity`warning  
A filter is called with the wrong number of arguments.
* unknown global`hubl/unknown-global`info  
An identifier isn't a known HubL global or local variable; codefmt suggests the closest match.
* unknown function`hubl/unknown-function`info  
A function call whose name isn't a known HubL function, a locally-defined macro, or an imported name. Method calls and filter calls are excluded.
* || instead of or`hubl/js-trap-or`error  
JavaScript's || used where HubL expects the keyword or.
* && instead of and`hubl/js-trap-and`error  
JavaScript's && used where HubL expects the keyword and.
* \=== instead of ==`hubl/js-trap-strict-eq`error  
JavaScript's === / !== used where HubL expects == / !=.
* null instead of none`hubl/js-trap-null`error  
The literal null used in a test where HubL expects none.
* backtick template literal`hubl/js-trap-template-literal`error  
A JavaScript backtick template literal, which HubL does not support.
* .forEach instead of a for tag`hubl/js-trap-foreach`info  
A JavaScript .forEach() used where HubL expects a {% for %} tag.

## inheritance

Mistakes in template inheritance: blocks, extends, and super().

* duplicate block name`hubl/duplicate-block-name`error  
Two {% block %}s share the same name in one template.
* missing endblock`hubl/missing-endblock`error  
A {% block %} has no matching {% endblock %}.
* super() outside a block`hubl/super-outside-block`error  
{{ super() }} is called outside any {% block %}.
* extends path not found`hubl/extends-path-not-found`errorneeds project context  
{% extends %} points to a template path that doesn't exist in the project. Requires project context.

## deprecation

Tags HubSpot has renamed; codefmt flags the old name and offers a safe one-click fix.

* deprecated tag`hubl/deprecated-tag`warning  
A deprecated tag such as widget or widget\_block that should be renamed to module or module\_block. Ships a safe one-click fix.

## module shape

Malformed module / dnd\_module declarations and field definitions.

* module missing path`hubl/module-missing-path`error  
A {% module %} or {% dnd\_module %} is missing its required path parameter.
* unknown field type`hubl/module-unknown-field-type`warning  
A module field declares a type HubL doesn't recognize.
* malformed module params`hubl/module-malformed-params`error  
A module parameter is malformed, e.g. form\_id 7a3 where the = was forgotten.
* unknown module name`hubl/module-unknown-name`warningneeds project context  
A {% module %} references a module name not found in the project. Requires project context.

## hints

Lower-severity smells: things that work but are worth a second look.

* nested raw block`hubl/nested-raw`warning  
A {% raw %} block nested inside another {% raw %}, which does not behave as it looks.
* empty block`hubl/empty-block`warning  
A block tag with no body content.
* |safe without |escape`hubl/unsafe-without-escape`info

|safe applied without a preceding |escape, a potential XSS footgun.
* large range loop`hubl/large-range`info  
range() iterating a very large number of times (over 1000), which can slow template rendering.

[run these checks in the HubL formatter and linter](/hubl)

related: [why standard linters can't read HubL](/hubspot-cms-linter), [codefmt vs. HubSpot's VS Code extension](/vs-hubspot-vscode)

primary source: [HubSpot: HubL syntax reference](https://developers.hubspot.com/docs/cms/reference/hubl/overview)
