Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
lessc compile error "Cannot call method 'charAt' of undefined" #592
When trying to compile Twitter's bootstrap via lessc, i found out this very strange behavior.
When i'm compiling within bootstrap's directory, everything works fine:
But when i go up one folder, it looks like
Why i need this? I've included bootstrap to my project via
I hope someone can reproduce this error.
Some additional information:
And another intressing part:
When cd-ing to bootstrap/ and building via
That error is the error I get everytime I have an error in one of the file I imported. It's actually kind of not handy, everytime there is a typo or an error in a file that is not the main file, you have no way to find out what it is unless you recompile each imported file one by one until you get the one that throws an error and tells you where it is.
The issue is that getInput() looks up file contents by e.filename and e.filename seems to be set differently depending on where you are relative to the target file.
Here is a example node debugger session that shows the issue:
To the developers:
I get the same problems when using browser inclusion: I have an "application.less" under "/stylesheets" which then includes bootstrap's main Less file from a subdirectory:
then my page source looks like this:
resulting in the error:
Interestingly, the "sprites.less" reference in the error is hyperlinked to "/sprites.less", which suggests that Less is confused about the paths.
Compilation using "lessc" works fine, so I'm seeing almost the opposite behavior to that observed by @philipp-spiess above.
I did try with compiling my stuff with 1.2.2 but it still has the same problem.
I finally diagnosed the problem and got to a solution I find acceptable. It is a problem related with scopes and timing.
The callback you pass when you call less.Parser.importer() at the top of "parser.js" is at the top importing files Parser scope. However, I think this callback only gets called and registers the content data (the actual less code text) ater an import is parsed. This might be to late for some parsing errors.
Anyway, when there is a parsing error - because there is actually an error on the Less source code which trigger this problem - the code handling the error does not have access to part of the data it counts on to perform its task.
As parte of the error handling, Less tries to display the offending code. It uses the getInput() function (at parse.js) to get that offending code. When it gets an undefined instead of a string of Less code and tries to cut a bit of it to display it, it cause an exception to be thrown. That is the origin of the weird error message reported at issue #592.
This is also why the error is intermittent. The problem at the error handling code is simply hiding the error message for the real problem. Eventually, the programmer fixes the original problem at his Less code and everything works again.
Therefore I tried to load the cache as soon as the less stylesheet code is loaded. Then, of course, it is necessary to pass the data to the top importing parser cache, which requires some reference passing.
I found a solution simple enough for me to feel confortable. Not beautiful, but I don't feel confortable making a big change on your code. Had to keep it as simple as possible.
I tested everything by:
Everything worked fine except for an unrelated issue, present also on 1.2.2 - resolving variables only on dynamic loading on url()s, like this one:
I also removed the use of basename() since it was vulnerable to name clashes - e.g.:
In my use cases I detected no problems about that either and I was careful to ensure all bits and pieces received as filename the name actually used by the loading logic (for both browser and node).
I will now commit and submit a pull request.
Pull request submitted at:
I am also running into this bug (with less 1.3.0 and Bootstrap 2.0.2 WIP).
My file imports bootstrap from a subfolder. There are no files with identical names.
Is there a workaround for this issue related to importing TB form a subfolder?
I am still having the issue. I have a submodule in
Here is my file structure:
Compiling it from the base gives the known error:
The underlying problem here is structural. For a bit of .less source there are two concepts: the actual physical resource from which it was loaded, which is the filename, and in the case of imports, the logical path: the name you use do an
Nodes in the syntax tree are only aware of the former, not the latter, so when generating errors, there is simply no clean way to reconcile a node to the logical path where its contents are cached. Rectify this structural deficiency and fixing this error will shake out nicely.
@paulogaspar7 This doesn't have anything to do with timing since I see it also in less.rb which runs in a fully synchronous fashion.
Who knows, maybe we can come up with a longer term fix together, for old times sake :)
This simple fix doesn't help when compiling (using rhino, node, or browser)