netdata/netdata · error · ParserError

expected the node content, but found %r

Error message

expected the node content, but found %r

What it means

ParserError raised by parse_node when a property (anchor '&' or tag '!') has been consumed but the token that follows cannot start node content in that position — e.g. a flow separator ',' or '}' directly after a tag, or a block-entry '-' on the same line after a tag. The parser expected a scalar/collection to attach the properties to.

Source

Thrown at src/collectors/python.d.plugin/python_modules/pyyaml3/parser.py:370

                    self.state = self.parse_block_sequence_first_entry
                elif block and self.check_token(BlockMappingStartToken):
                    end_mark = self.peek_token().start_mark
                    event = MappingStartEvent(anchor, tag, implicit,
                            start_mark, end_mark, flow_style=False)
                    self.state = self.parse_block_mapping_first_key
                elif anchor is not None or tag is not None:
                    # Empty scalars are allowed even if a tag or an anchor is
                    # specified.
                    event = ScalarEvent(anchor, tag, (implicit, False), '',
                            start_mark, end_mark)
                    self.state = self.states.pop()
                else:
                    if block:
                        node = 'block'
                    else:
                        node = 'flow'
                    token = self.peek_token()
                    raise ParserError("while parsing a %s node" % node, start_mark,
                            "expected the node content, but found %r" % token.id,
                            token.start_mark)
        return event

    # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END

    def parse_block_sequence_first_entry(self):
        token = self.get_token()
        self.marks.append(token.start_mark)
        return self.parse_block_sequence_entry()

    def parse_block_sequence_entry(self):
        if self.check_token(BlockEntryToken):
            token = self.get_token()
            if not self.check_token(BlockEntryToken, BlockEndToken):
                self.states.append(self.parse_block_sequence_entry)
                return self.parse_block_node()
            else:

View on GitHub (pinned to 4864de85e2)

Solutions

  1. Put the node the tag applies to immediately after it: 'k: !!str "12"'.
  2. For block collections, start the sequence on the next line: 'k: !!seq' followed by an indented '- item'.
  3. Remove the stray '&'/'!' property if the value was deleted.
  4. Re-run yaml.safe_load() to verify.

Example fix

# before
key: !!str - item

# after
key: !!str "item"
Defensive patterns

Strategy: try-catch

Validate before calling

import re, yaml

def tags_attached_to_nodes(text):
    # a property immediately followed by a flow separator is dangling
    bad = [i + 1 for i, l in enumerate(text.splitlines())
           if re.search(r'(!!?\S+|&\w+)\s*[,\]}]', l)]
    return not bad

Type guard

def is_node_content_error(exc):
    return isinstance(exc, yaml.parser.ParserError) and 'expected the node content' in str(exc)

Try / catch

try:
    cfg = yaml.safe_load(text)
except yaml.parser.ParserError as e:
    if 'expected the node content' in str(e):
        report('a tag/anchor must be immediately followed by its node value')

Prevention

When it happens

Trigger: yaml.safe_load() on input like '{a: !str, b: 1}' (tag then ','), 'k: !!str - item' (tag and sequence entry on one line), or a dangling 'k: !tag' followed by a token that is not a value in that context.

Common situations: Fixing a value's type by adding '!!str'/'!!int' in the wrong place; writing a tagged block sequence on a single line; leftover anchors/tags after deleting a value.

Related errors


AI-assisted analysis of netdata/netdata@4864de85e2 (2026-08-15). Data as JSON: /api/errors/2e4b931843ff4977. Report an issue: GitHub.