Haml Errors Suck
I love it when people rant about Haml and Sass. As wonderful as positive feedback is (and I love that, too), criticism is golden. Hearing what people hate about these programs is hands-down the best way to figure out how to improve them.
For example, people hated that Haml was so much slower than ERB.
It’s not any more1.
People hated that it was so annoying to format whitespace-sensitive HTML elements like textarea and pre.
This will “just work” as of the next major release.
Unfortunately, there’s one major issue I haven’t been able to fix. I’ve heard over and over again on blog posts and Twitter that people just can’t understand Haml’s and Sass’s error messages.
I’m in a tricky position. Since I understand all the inner workings of Haml and Sass, error messages that seem clear to me may be totally opaque to most people. In addition, I wrote almost all the error messages anyway. So I can’t tell which ones are unclear or how to make them moreso.
That’s why I’m asking anyone who’s used Haml and Sass, and especially anyone who hates their error messages, for help. I want you to help me make the error messages as clear as they can possibly be.
To help with this, I’ve compiled a list of all the error messages, with brief descriptions and example code demonstrating the issue. If you have a better error message for any of them, please post a comment or email the mailing list about it.
Let’s begin with Haml’s error messages; once we’ve made them wonderful, we’ll go work on Sass’s.
Haml Errors
Illegal Indentation: Only two space characters are allowed as tabulation.
Too many or too few spaces or one or more tab characters are used when indenting in Haml.%span foo
Illegal Indentation: Indenting more than once per line is illegal.
A line is indented four or more spaces deeper than the previous line.Unintuitively, this error message appears even for an odd number of spaces.
It would probably be a good idea to merge this with the previous error.
%span fooIllegal Nesting: Nesting within plain text is illegal.
A line is indented following a plain-text line.This is plain text. This is indented.
Tag has no content.
~,%tag~, or%tag=is used without having any Ruby code to evaluate.Just using
=without any Ruby code doesn’t generate this error; this is a bug.%span=
Invalid tag: ”#{tag}”
A tag is in some way malformed.This is more of a catch-all error… most invalid tags trigger more specific errors. A tag without a name (just
%) will trigger it, though.%
Illegal element: classes and ids must have values.
A tag uses#or.without supplying a class or id name, respectively.%span#
Illegal Nesting: Nesting within an atomic tag is illegal.
A line is indented following a auto-closed (atomic) tag.%br/ This is indented
Atomic tags can’t have content.
A tag is marked as atomic but still has content.%br/ Foo
Illegal Nesting: Content can’t be both given on the same line as #{tag} and nested within it.
A tag has both inline and nested content.%span Foo Bar
Illegal Nesting: Nesting within a tag that already has content is illegal.
A comment has both inline and nested content.This should probably be merged with the previous error.
/* Foo Bar
Illegal Nesting: Nesting within a header command is illegal.
A line is indented following a!!!header.!!! Foo
Filters must have nested text.
A filter is used without nesting text beneath it.It might be a good idea to just have this pass the empty string to the filter.
:textile
Unbalanced brackets.
A tag has unbalanced curly braces or square brackets.%span{:style => 'color: blue'
And that’s it. Writing all those down has certainly been a lesson in humility for me. I can see how some of them would confuse people. But hopefully we’ll be able to fix that!
1 Once again, immeasurable thanks to Tom Bagby for spearheading the effort to optimize Haml.
About Me
Feed
Git-Style Automatic Paging in Ruby



Is it just me, or are your 1-line explanations better in most cases than the original error messages? From a satisfied (if spare time only) haml user!
The worst thing I’ve encountered is no message and no output at all. This is rare but sometimes occurs when I’m several layers deep in partial rendering and have an error in my template. I get no errors in the log and no rendered output :/ I’ll try to put together an example later if I’m able.
In general the errors have made sense to me. Its when none are available the debugging is difficult.
For the illegal indentation errors, it would be very helpful if the illegal characters could be highlighted in some way. In general, it would be useful if there were more hints about exactly which characters are causing an error, and how said error might be fixed.
For me, it isn’t the standard haml errors that suck. It’s the ones where you do something that results in a parse error from ruby as it’s trying to parse the code Haml has generated. These are hard to track down. One place where I sometimes get this is when I do
%h1{:style=>"display:none;"}==#{'a string'}or something like this, it complains about mismatched brackets but then if I do:
%h1{:style=>"display:none;"} ==#{'a string'}it’s fixed. The error message is entirely cryptic though, and not one of those above.
Mike: I thought about that while I was writing them. In general, I think while some of my descriptions here work better, they still tend to betray a lot of foreknowledge about Haml that I’d like to avoid.
Jeff: The only reliable cause of no-output error’s I’ve found (and believe me, I’ve looked) is when a Rails error template for some reason fails to render. There are several reasons this happens, but all the one’s I’ve found aren’t fixable from within Haml.
Jon: That’s a good idea. I’m not sure how I’d go about highlighting the characters themselves, but I’ll see if I can work them into the error messages.
Ryan: The particular issue you point out is a Haml bug that’s been fixed in recent versions, but Ruby parse errors are tricky in general. It’s hard to translate from the Ruby code back to the Haml template. It may be possible, though… I’ll poke around with it.
I find the worst haml errors are a completely blank page
I’ve been playing around with how Haml errors interact with various versions of Rails, and it looks like in Rails versions less than 2.0.2, compile-time Haml errors render as a blank page. I hadn’t known about this before; I’ll get to fixing it right away.
@Mike: agreed! Maybe a balance needs to be struck here…
Okay, after spending some time playing around with various versions of Rails, I think all Haml errors should render properly in all of them except Edge. Edge needs a patch which Pratik Naik (a.k.a. lifo) will apply tomorrow.
There is only really one error that is really hard to handle, it is the parsing errors. These are hard to handle and debug because HAML’s output and the parser line error numbers do not correlate.
There error might be on line 40 of the compiled output, but in the HAML file with it’s terse goodness, the error actually appears on line 15 or something.
If there could be a way of outputting the parsed / compiled / formatted HTML / Ruby in those Ruby syntax dumps with meaningful line numbers, THAT would help a lot.
All the other error messages I really don’t have problems with.
Mikel
Thanks for HAML and SASS by the way, they are a life saver :)
Haml’s always tried to figure out which line of Haml a given Ruby error corresponds to. This was accomplished in various hacky ways until I decided to do the sane thing and have the compiled Ruby code matches up line-for-line with the Haml file. This is how it’s been since 1.8 (I think) so line numbers should have been working reasonably well.
Unfortunately, even still they didn’t always. However, with this latest round of fixes I’ve fixed every line number error I’ve been able to find. If you see any more with the latest master branch from git, let me know.
Also, you’re welcome :-).
One thing I sometimes get backwards is the following:
%span[user]{:other_attribute => 'something'} %span{:other_attribute => 'something'}[user]IIRC the error for this was very general. A more specific error with an example of the required order would be great.
Good thought, Jack. I’ll see what I can do about making the “invalid tag” errors more specific.
Jack, I decided that rather than have a detailed error message when transposing object_refs and attributes, I’d just allow the object_ref to go in front of the attributes. The two forms you posted are synonymous now.