Nanoc»Troubleshooting

Error: “Found 3 content files for X; expected 0 or 1”

This error occurs for legacy identifiers when there are multiple files with the same base name, but different extensions. When using legacy identifiers, Nanoc requires each base name to be unique. For example, the following situation will give raise to this error:

content/assets/fonts/foo.eot
content/assets/fonts/foo.otf

Nanoc converts these filenames to identifiers which do not contain the file extension. In the example given above, both filenames correspond to the identifier /assets/fonts/foo/. Identifiers are required to be unique, and thus Nanoc raises an error.

New in Nanoc 4 are full identifiers, which contain the file extension. We recommend upgrading to Nanoc 4 and enabling full identifiers as well as glob patterns. For details, see the Nanoc 4 upgrade guide page and the Identifiers and patterns page.

Error: “can’t modify frozen…”

Once the compilation process has started, content, and attributes of layouts and items are frozen, which means they cannot be modified anymore. For example, the following rule is invalid and will cause a “can’t modify frozen Array” error:

compile '/articles/**/*'
  item[:tags] << 'article'
  filter :erb
  layout 'default'
end

What is possible, is modifying content and attributes in the preprocess phase. The preprocess phase is defined using the preprocess block in the Rules file (see the Rules page). For example:

preprocess do
  items.select { |i| i.identifier =~ '/articles/**/*' }.each do |i|
    i[:tags] << 'article'
  end
end

Error: “Textual filters cannot be used on binary items”

There are two item types in Nanoc: textual and binary. Most filters that come with Nanoc, such as :erb and :haml, are textual, meaning they take text as input and produce new text. It is also possible to define binary filters, such as an image thumbnail filter.

It is not possible to run a textual filter on binary items; for example, running :erb on an item with filename content/assets/images/puppy.jpg will cause the “Textual filters cannot be used on binary items” error.

When you are getting this error unexpectedly, double-check your Rules file and make sure that no binary item is filtered through a textual filter. Remember that Nanoc will use the first matching rule only!

Character encoding issues

Character encoding issues manifest themselves in two ways:

  • Some characters do not show up correctly in the output (e.g., ä shows up as ä).

  • Nanoc exits with an error such as RegexpError: invalid multibyte character.

In both cases, text in one character encoding is erroneously interpreted as a different character encoding. There are two possible causes for this.

Wrong output encoding tag

The text could be in the correct encoding, but Nanoc or the browser interpret it wrongly.

Nanoc’s output is always UTF-8, so the output files should not declare a different encoding. For example, having <meta charset="iso-8859-1"> at the top of files in output/ is wrong: it should be <meta charset="utf-8"> instead. You should also ensure that your web server sends the right Content-Type.

Wrong input encoding

The data sources could interpret the input data in the wrong encoding.

Nanoc defaults to the current environment encoding, which might not be what you expect. If the environment encoding does not match the actual file encoding, it can lead to errors in the output. There are three ways to solve this:

  • You can re-encode your site’s files. If your content files are not in UTF-8, this is probably a good start. Re-encoding into something else than UTF-8 is not recommended.

  • You can modify your environment encoding to match the file encoding. If you run into encoding issues with other sites or libraries, it isn’t a bad idea to set your environment up as UTF-8 and get it over with. You should not change your environment to a non-UTF-8 encoding, as UTF-8 is considered the standard character encoding.

  • You can set an explicit encoding in the Nanoc configuration file. This is the recommended approach, as it never hurts to be explicit.

To set the encoding explicitly in the site configuration, open nanoc.yaml (or config.yaml on older Nanoc sites) and navigate to the section where the data sources are defined. Unless you have modified this section, you will find a single entry for the filesystem data source there. In this section, add something similar to encoding: utf-8 (replacing utf-8 with whatever you really want). It could look like this:

data_sources:
  -
    type: filesystem
    encoding: utf-8

For bonus points, you can do all three. Setting up your content, environment, and configuration as UTF-8 is the best way to avoid encoding issues now and in the future.

Timestamps in YAML files parsed incorrectly

If you work with date/time attributes (such as created_at, published_at, and updated_at) and find that the time is one or more hours off, then this section applies to you.

If you use timestamps in the YAML file, be sure to include the timezone. If no timezone is specified, then UTC is assumed—not the local time zone! Quoting the YAML timestamp specification:

If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part may be omitted altogether, resulting in a date format. In such a case, the time part is assumed to be 00:00:00Z (start of day, UTC).

We recommend always specifying the time zone.

Hidden files are ignored

Nanoc by default intentionally ignores files and directories that have a name that starts with a period. Such files and directories are hidden on Unix-like systems, such as OS X and Linux. Nanoc does so because these hidden files and directories are often generated unintentionally; for instance, OS X will generate .DS_Store files, and vim generates backup files with a name like .about.md.un~.

The filesystem data source can be told to include specific files that would otherwise be ignored. To do so, specify in the data source’s extra_files attribute the patterns for the files that you would like to be included. For example, the following will include GitHub’s .nojekyll file and all files in the .well-known/ directory:

data_sources:
  -
    type: filesystem
    extra_files:
      - "/.well-known/**/*"
      - "/.nojekyll"

Alternatively, route a file whose name does not start with a slash to a path that starts with a slash. For example, the following will copy content/nojekyll to output/.nojekyll:

compile '/nojekyll' do
  write '/.nojekyll'
end

My helper methods cause a NoMethodError!

When calling a method in a helper results in a NoMethodError, you might not have activated the helper. To activate a helper, include it, like this (in a file in the lib/ directory, such as lib/helpers.rb):

include Nanoc::Helpers::Blogging

Make sure to double-check the spelling of the method that is being invoked.