Skip to content

Article

Seven HubSpot theme bugs that fail without an error

The short answer

The worst HubSpot theme bugs upload cleanly and render nothing. Seven silent HubL failures we hit building Content Hub themes, and how to catch each one.

A code window with one line flagged as a silent failure

A HubSpot theme bug that throws an error is a good bug. You see it, you fix it. The expensive ones upload with a green tick, render a page, and quietly leave something out.

These seven cost us real hours across two Content Hub theme builds this year. Each one is now a check in our validator, so it cannot reach a client portal again.

1. Module parameters are not expressions

Passing a variable into a module from a coded template looks obvious and does not work:

{% module "hero" path="../modules/hero" headline=page.headline %}

That renders the literal text page.headline. Parameters only evaluate inside interpolation, so write headline="{{ page.headline }}".

2. Lists passed to modules vanish

Worse than the first: pass a list to a repeater field and the section renders with its heading and no items. No error anywhere. Our fix is a hidden text field on every repeater module that accepts JSON, which the module parses back into a list:

data_json='{{ cards|tojson }}'

Use single quotes on the parameter, because tojson emits double quotes, and never put a straight apostrophe in the data.

3. "and not" is not what you think

A condition like {% if a and not b %} can coerce a string operand to false and skip the block silently. Nest the conditions or compare explicitly. It reads worse and works every time.

4. Global module defaults stop mattering after the first render

A global module saves its content into the portal the first time it renders. After that, changing the defaults in fields.json uploads cleanly and changes nothing on the site. We render headers and footers from a generated literal inside module.html instead, synced from fields.json by a script that runs before every deploy.

If you change a nav in code and the site does not change, this is why.

5. The portal path has no .theme suffix

The theme folder on disk is my-theme.theme. In the portal it is my-theme. Create a page over the API pointing at the on disk path and you get HTTP 200 and a blank document. The only clue is an HTML comment saying the template is missing.

6. Two full width modules in one row

Two width=12 modules inside the same dnd_row passes a local lint and fails at upload with an error that names the wrong line. One full width module per row.

7. The form is gone when HubSpot says it was submitted

Code that waits for the submitted event and then reads values from the form finds nothing, because HubSpot has already swapped the form for its thank you message. Capture the form ID and values on input and submit, then treat the submitted message appearing as the signal. Our audit gate sat on "Connecting you" for a day because of this.

How we catch them now

TrapCheck
Bare variables in module tagsValidator flags any parameter value that is not a literal or interpolated
Lists into repeatersEvery repeater module ships a JSON field; lists passed directly fail the build
Global module defaultsNav and footer rendered from synced literals; sync runs in the deploy script
Theme pathAPI scripts resolve the portal path, never the disk path
Two full width modulesRow width totals checked before upload
Form submit timingShared handoff script used by every gated form

The pattern across all seven is the same: HubSpot is forgiving by design, so the platform will not tell you when you are wrong. A validator chained to every upload does. If your theme has a bug nobody can explain, send us the repo.

Talk to us

Tell us what is going on.

One form, one reply, from the person who would do the work. No sequence, no SDR, no chasing.

  • A reply within one working day
  • From a dedicated specialist, not an account manager
  • No sales sequence unless you ask for one

Rather pick a time now?

Book a call

Protected by reCAPTCHA. We do not sell, share or rent your details.