Handle Unresolved References

When you reference a missing attribute (e.g., {does-not-exist}), the AsciiDoc processor will leave the attribute reference behind. If you undefine an attribute on the same line as other text (e.g., {set:attribute-no-more!}), the processor will drop the whole line. You can tailor these behaviors using the attribute-missing and attribute-undefined attributes. You’ll want to think about how you want the processor to handle these situations and configure the processor accordingly.

Missing attribute

The attribute-missing attribute controls how missing references are handled. By default, missing references are left behind so the integrity of the document is preserved and it’s easy for the author to track down.

This attribute has four possible values:

skip

leave the reference in place (default setting)

drop

drop the reference, but not the line

drop-line

drop the line on which the reference occurs (matches behavior of AsciiDoc.py)

warn

print a warning about the missing attribute

The setting you might find of most interest is warn, which gives you a warning whenever the processor encounters an attribute reference that cannot be resolved, but otherwise leaves the line alone.

Consider the following line:

Hello, {name}!

Here’s how the line is handled in each case, assuming the name attribute is not defined:

attribute-missing value Result

skip

Hello, {name}!

drop

Hello, !

drop-line

warn

asciidoctor: WARNING: skipping reference to missing attribute: XYZ

History
AsciiDoc.py always drops the line that contains a reference to a missing attribute (effectively attribute-missing=drop-line). This “feature” was a side effect of how the processor was implemented and not designed with the writer in mind. The behavior is frustrating for the writer because it’s hard to detect where its occurring and can result in loss of important content. That’s why Asciidoctor uses a different default behavior and, further, allows the behavior to be customized.

There are a few cases where the attribute-missing attribute is not strictly honored. One of those cases is the include directive. If a missing attribute is found in the target of an include directive, the processor will issue a warning about the missing attribute and leave behind the same warning message in the converted document.

Another case is the ifeval directive. A missing attribute reference can safely be used in the clause of the ifeval directive without any side effects (i.e., drop) since the purpose of that statement is to determine whether an attribute resolves to a value.

Forcing failure

If you want the processor to fail when the document contains a missing attribute, set the attribute-missing attribute to warn and pass the --failure-level=WARN option to the CLI.

$ asciidoctor -a attribute-missing=warn --failure-level=WARN doc.adoc

The processor will convert the entire document, but the application will complete with a non-zero exit status.

When using the API, you can consult the logger for the max severity of all messages reported or look for specific messages in the stack. It’s up to the application code to decide how and when to terminate the application.

Undefined attribute

The attribute-undefined attribute controls how expressions that undefine an attribute are handled. By default, the line is dropped since the expression is a statement, not content.

This attribute has two possible values:

drop

substitute the expression with an empty string after processing it

drop-line

drop the line that contains this expression (default setting; matches behavior of AsciiDoc.py)

The option skip doesn’t make sense here since the statement is not intended to produce content.

Consider the following declaration:

{set:name!}

Depending on whether attribute-undefined is drop or drop-line, either the statement or the line that contains it will be discarded. It’s reasonable to stick with the compliant behavior, drop-line, in this case.

We recommend putting any statement that undefines an attribute on a line by itself.