You are currently offline, serving cached version

Error handling

This section is about how to handle Docxtemplater errors.

With the errorLogging parameter, you can define whether you want to also automatically log the errors to stdout. This is documented here.

There are two points in the code where an error could occur :

In this code below, both lines can trigger an error (TemplateError or RenderingError).

// The line below can throw an error if the template itself is not valid (sometimes called TemplateError)
const doc = new Docxtemplater(zip, {
    paragraphLoop: true,
    linebreaks: true,
});
// The line below can throw an error if the parser execution fails or the data resolving fails. (sometimes called RenderingError)
doc.renderAsync({
    first_name: "John",
    last_name: "Doe",
    phone: "0652455478",
    description: "New Website",
});

When you catch the errors, you can handle the errors like this :

let doc;
try {
    /*
     * The line below can throw an error if the template itself is not valid
     * (sometimes called TemplateError)
     */
    doc = new Docxtemplater(zip, {
        paragraphLoop: true,
        linebreaks: true,
    });
    /*
     * The line below can throw an error if the parser execution fails or the
     * data resolving fails.
     */
    doc.render(/* data */);
} catch (error) {
    if (
        error.properties &&
        error.properties.errors instanceof Array
    ) {
        const errorMessages = error.properties.errors
            .map((error) => error.properties.explanation)
            .join("\n");
        console.log("errorMessages", errorMessages);
        /*
         * errorMessages is a humanly readable message looking like this:
         * 'The tag beginning with "foobar" is unopened'
         */
    }
    throw error;
}

In most cases, docxtemplater will throw a "MultiError", which is an error in the template that tells you that there are multiple errors in the document, and those errors can be accessed by looping over "error.properties.errors".

Error Schema

All errors thrown by docxtemplater follow this schema:

{
    name: One of ["MultiError", "GenericError", "TemplateError", "ScopeParserError", "InternalError"],
    message: The message of that error,
    properties : {
        explanation: An error that is user friendly (in english), explaining what failed exactly. This error could be shown as is to end users
        id: An identifier of the error that is unique for that type of Error
        ... : The other properties are specific to each type of error.
    }
}

Error example

If the content of your template is {user {name}, docxtemplater will throw a "Multi error", which allows you to retrieve all errors inside the Array "e.properties.errors" :

try {
    const doc = new Docxtemplater(zip, {
        paragraphLoop: true,
        linebreaks: true,
    });
    doc.render();
} catch (e) {
    /*
     * All these expressions are true
     * e.properties.id === "multi_error",
     * e.properties.explanation === "The template has multiple errors"
     * e.name === "TemplateError",
     * e.message === "Multi error",
     */

    const firstError = e.properties.errors[0];
    /*
     * All these expressions are true
     * firstError.name === "TemplateError",
     * firstError.message === "Unclosed tag",
     * firstError.properties.explanation === "The tag beginning with '{user ' is unclosed",
     * firstError.properties.id === "unclosed_tag",
     * firstError.properties.context === "{user ",
     * firstError.properties.xtag === "user",
     * firstError.properties.file === "word/document.xml"
     */
}

List of all Error Identifiers

All errors can be identified with their id (e.properties.id).

The ids are the following

Error Lists :

Error : api_version_error

This error arises when a recent module version necessitates a more current version of the docxtemplater core. Docxtemplater specifies an "APIVersion," and if a module requires API Version 3.55 or higher, but the docxtemplater instance provides API 3.52, this error will occur. To resolve this issue, please update to the latest version of docxtemplater.

Error : multi_error

This error is an Error that contains all template errors. It is a multi error because it contains all errors of the template in : err.properties.errors.

You can then map on each sub error like this :

for (const err of error.properties.errors) {
  console.log(err.properties.explanation);
}

Error : unopened_tag

This error happens if a tag is closed but not opened. For example with the following template:

Hello name} !
error.properties.explanation = `The tag beginning with "${options.xtag.substr(0,30)}" is unopened`

Error : duplicate_open_tag

This error happens with following template :

Hello
error.properties.explanation = `The tag ending with "${options.xtag.substr(0,30)}" has duplicate close tags`

Error : unclosed_tag

This error happens if a tag is opened but not closed. For example with the following template:

Hello {name !
error.properties.explanation = `The tag beginning with "${options.xtag.substr(0,30)}" is unclosed`

Error : no_xml_tag_found_at_left

This error is not directly linked to the template, it means that some tag tried to expand to adjacent XML tags, but those elements cannot be accessed from the current node.

This error happens if a rawXMLTag doesn't find a <w:p> element

<w:p><w:t>{@raw}</w:t>
// Note that the `</w:p>` tag is missing.
error.properties.explanation = `No tag "${options.element}" was found at the left`

Error : no_xml_tag_found_at_left

This error is not directly linked to the template, it means that some tag tried to expand to adjacent XML tags, but those elements cannot be accessed from the current node.

error.properties.explanation = `No tag "${options.element}" was found at the left`

Error : invalid_xml_characters

This error prevents the docx document to become corrupt. It happens if you're trying to render text that would produce invalid XML output.

See #corrupt-character-error on how this can be fixed by changing your parser.

error.properties.explanation = `There are some corrupt characters for the field "${tag}"`

Error : invalid_raw_xml_value

This error happens if you try to render a rawXml tag, such as : {@raw} And the value of the data for "raw" is truthy but not a string.

(If the value of the data is falsy, than the tag is simply dropped and no error is thrown)

error.properties.explanation = `The value of the raw tag : "${partDelims}" is not a string`

Error : raw_xml_tag_should_be_only_text_in_paragraph

This happens when a rawXMLTag {@raw} is not the only text in the paragraph. For example, writing {@raw} (Note the spaces) is not acceptable because the {@raw} tag replaces the full paragraph. We prefer to throw an Error now rather than have "strange behavior" because the spaces "disappeared".

To correct this error, you have to add manually the text that you want in your raw tag. (Or you can use the docxtemplater word-run module which adds a tag that can replace rawXML inside a tag).

Writing

{@my_first_tag}{my_second_tag}

Or even

Hello {@my_first_tag}

Is misusing docxtemplater.

The @ at the beginning means "replace the xml of the current paragraph with scope.my_first_tag" so that means that everything else in that Paragraph will be removed.

error.properties.explanation = `The raw tag "${tag}" should be the only text in this paragraph. This means that this tag should not be surrounded by any text or spaces.`

Error : unbalanced_loop_tags

This error happens if you create a table and misplace tags inside the table :

Head1Head2
{#a}X{/a}{#b}Y{/b}

In the case above, the {#a} and {/a} will expand to the whole loop, but this is not possible because of the other loop in {#b}Y{/b}

Instead, you should usually write :

Head1Head2
{#a}X{#b}Y{/b}{/a}
error.properties.explanation = `Unbalanced loop tags {#${lastL}}{/${lastR}}{#${l}}{/${r}}`

Error : closing_tag_does_not_match_opening_tag

This error happens if your loop tags are incorrectly closed

{#condition1}
Some text
{/otherCondition}

Since the start tag does not match the open tag, the template is invalid.

error.properties.explanation = `The tag "${tags[0].value}" is closed by the tag "${tags[1].value}"`

Error : scopeparser_compilation_failed

This happens when your parser throws an error during compilation. The parser is the second argument of the constructor new Docxtemplater(zip, {parser: function parser(tag) {}});

For example, if your template is:

{name++}

and you use the angular expression parser, you will have this error. The error happens when you call parser('name++'); The underlying error can be read in e.properties.rootError

error.properties.explanation = `The scope parser for the tag "${tag}" failed to compile`

Error : scopeparser_execution_failed

This happens when your parser throws an error during execution. The parser is the second argument of the constructor new Docxtemplater(zip, {parser: function parser(tag) {}});

For example, if your template is:

{test | toFixed}

and your code is :

const expressionParser = require("docxtemplater/expressions.js");
const doc = new Docxtemplater(zip, {
  paragraphLoop: true,
  linebreaks: true,
  parser: expressionParser.configure({
    filters: {
      toFixed(input) {
        return input.toFixed();
      }
    }
  }),
});
doc.render({
  test: false
});

Since false.toFixed() triggers an error in Javascript, this will then throw an error "Scope parser execution failed".

You can either fix your data or make your toFixed function more robust by returning "input" if the input is not a number.

error.properties.explanation = `The scope parser for the tag ${tag} failed to execute`

Error : loop_position_invalid

This happens when a loop would produce invalid XML.

For example, if you write:

Head1Head2
{#users}content

{/users}

this is not allowed since a loop that starts in a table must also end in that table.

error.properties.explanation = `The tags "${tag}" are misplaced in the document, for example one of them is in a table and the other one outside the table`

Error : unimplemented_tag_type

This happens when a tag type is not implemented. It should normally not happen, unless you changed docxtemplater code or created your own module and didn't implement the render function of your module correctly.

Error : malformed_xml

This happens when an xml file of the document cannot be parsed correctly.

Error : resolve_before_compile

This happens if you're calling resolveData() before you run .compile().

You should always call compile first and then only resolveData

Or you can migrate to the constructor with two arguments

Error : render_on_invalid_template

This happens if you're calling render() on a document that had template errors

Error : render_twice

This happens if you're calling render() on a document twice.

You should always create a new docxtemplater instance if you need to create two output documents.

Error : filetype_not_identified

This error happens if you're creating docxtemplater with a zip file, but that file is not recognized as a docx/pptx/xlsx or odt file.

Note that xlsx files and odt files need a paid module to be templated.

Other zip files (zip, odp, ods) will trigger the same error.

error.properties.explanation = `The filetype for this file could not be identified, is this file corrupted ? ${msg}`

Error : file_has_invalid_xml

This error happens if the XML is invalid in your template file.

This should be very rare except if you were using a tool to preprocess the template (an XML error in a docx file means that the template file is already corrupt).

Error : filetype_not_handled

This error happens if the filetype was recognized (xlsx, odt), but without the correct module, this file cannot be templated

error.properties.explanation = `The file you are trying to generate is of type "${fileType}", but only docx and pptx formats are handled`

Cannot attach a module that was already attached

You might get this error:

Cannot attach a module that was already attached: "ImageModule". Maybe you are
instantiating the module at the root level, and using it for multiple instances
of Docxtemplater

In previous versions the error was Cannot attach a module that was already attached.

This happens if you are reusing the same module instance twice.

It usually means that you are calling new ImageModule() just once, but you have to instantiate a new ImageModule instance for each docxtemplater instance.

The following code will throw the error when calling "generate" twice:

const Docxtemplater = require("docxtemplater");
const ImageModule = require("docxtemplater-image-module");

const imageOptions = {
    getImage(tagValue, tagName, meta) {
        console.log({ tagValue, tagName, meta });
        return fs.readFileSync(tagValue);
    },
    getSize() {
        // it also is possible to return a size in centimeters, like this : return [ "2cm", "3cm" ];
        return [150, 150];
    },
};

const imageModule = new ImageModule(imageOptions);

function generate(content) {
    const zip = new PizZip(content);
    const doc = new Docxtemplater(zip, {
        modules: [imageModule],
    });
    doc.render(data);
}

generate();
generate();

You must always reconstruct an imageModule for each Docxtemplater instance.

The following code will no more throw the error:

const Docxtemplater = require("docxtemplater");
const ImageModule = require("docxtemplater-image-module");
const imageOptions = {
    getImage(tagValue, tagName, meta) {
        console.log({ tagValue, tagName, meta });
        return fs.readFileSync(tagValue);
    },
    getSize() {
        // it also is possible to return a size in centimeters, like this : return [ "2cm", "3cm" ];
        return [150, 150];
    },
};

function generate(content) {
    const zip = new PizZip(content);
    const imageModule = new ImageModule(imageOptions);
    const doc = new Docxtemplater(zip, {
        paragraphLoop: true,
        linebreaks: true,
        modules: [imageModule],
    });
    doc.render(data);
}

generate();
generate();

Corrupt character error

It is possible that you can get the following error :

{
    message: "There are some XML corrupt characters",
    properties: {
        id: "invalid_xml_characters",
    }
}

This means that some characters in your data contains some strange character.

You can either make sure your data does not contain one of those invalid characters, or you can use this solution to remove all corruptCharacters from your data :

const corruptCharacters = /[\x00-\x08\x0B\x0C\x0E-\x1F]/g;
/*
 * 00    NUL '\0' (null character)
 * 01    SOH (start of heading)
 * 02    STX (start of text)
 * 03    ETX (end of text)
 * 04    EOT (end of transmission)
 * 05    ENQ (enquiry)
 * 06    ACK (acknowledge)
 * 07    BEL '\a' (bell)
 * 08    BS  '\b' (backspace)
 * 0B    VT  '\v' (vertical tab)
 * 0C    FF  '\f' (form feed)
 * 0E    SO  (shift out)
 * 0F    SI  (shift in)
 * 10    DLE (data link escape)
 * 11    DC1 (device control 1)
 * 12    DC2 (device control 2)
 * 13    DC3 (device control 3)
 * 14    DC4 (device control 4)
 * 15    NAK (negative ack.)
 * 16    SYN (synchronous idle)
 * 17    ETB (end of trans. blk)
 * 18    CAN (cancel)
 * 19    EM  (end of medium)
 * 1A    SUB (substitute)
 * 1B    ESC (escape)
 * 1C    FS  (file separator)
 * 1D    GS  (group separator)
 * 1E    RS  (record separator)
 * 1F    US  (unit separator)
 */
function stripCorruptChars(str) {
    return str.replace(corruptCharacters, "");
}

function parser(tag) {
    return {
        get(scope) {
            let result = null;
            if (tag === ".") {
                result = scope;
            } else if (scope) {
                result = scope[tag];
            } else {
                result = scope;
            }
            if (typeof result === "string") {
                return stripCorruptChars(result);
            }
            return result;
        },
    };
}

const doc = new Docxtemplater(zip, {
    paragraphLoop: true,
    linebreaks: true,
    parser,
});
doc.render(/* data */);
Talk with sales Contact us