netdata/netdata · error · ScannerError
expected a digit or ' ', but found %r
Error message
expected a digit or ' ', but found %r
What it means
Raised at the end of scan_yaml_directive_value: after the minor version number of a %YAML directive, only end-of-line, EOF, or a comment may follow. Trailing garbage after '%YAML 1.1' (extra token, letter, or dot) fails this check while scanning the directive.
Source
Thrown at src/collectors/python.d.plugin/python_modules/pyyaml3/scanner.py:841
if ch not in '\0 \r\n\x85\u2028\u2029':
raise ScannerError("while scanning a directive", start_mark,
"expected alphabetic or numeric character, but found %r"
% ch, self.get_mark())
return value
def scan_yaml_directive_value(self, start_mark):
# See the specification for details.
while self.peek() == ' ':
self.forward()
major = self.scan_yaml_directive_number(start_mark)
if self.peek() != '.':
raise ScannerError("while scanning a directive", start_mark,
"expected a digit or '.', but found %r" % self.peek(),
self.get_mark())
self.forward()
minor = self.scan_yaml_directive_number(start_mark)
if self.peek() not in '\0 \r\n\x85\u2028\u2029':
raise ScannerError("while scanning a directive", start_mark,
"expected a digit or ' ', but found %r" % self.peek(),
self.get_mark())
return (major, minor)
def scan_yaml_directive_number(self, start_mark):
# See the specification for details.
ch = self.peek()
if not ('0' <= ch <= '9'):
raise ScannerError("while scanning a directive", start_mark,
"expected a digit, but found %r" % ch, self.get_mark())
length = 0
while '0' <= self.peek(length) <= '9':
length += 1
value = int(self.prefix(length))
self.forward(length)
return value
def scan_tag_directive_value(self, start_mark):View on GitHub (pinned to 4864de85e2)
Solutions
- Put anything after the version on its own line or make it a comment: '%YAML 1.2 # standard'.
- Remove trailing tokens so the directive line ends right after the minor number.
- Re-validate the file parses.
Example fix
# before %YAML 1.2 standard --- a: 1 # after %YAML 1.2 # standard --- a: 1
Defensive patterns
Strategy: validation
Validate before calling
import re
def no_trailing_after_version(text):
return all(re.match(r'^%YAML\s+\d+\.\d+(\s*#.*)?\s*$', l)
for l in text.splitlines() if l.startswith('%YAML')) Type guard
def is_directive_tail_error(exc):
return isinstance(exc, yaml.scanner.ScannerError) and 'digit or' in str(exc) and 'directive' in str(exc) Try / catch
try:
yaml.safe_load(text)
except yaml.scanner.ScannerError as e:
report('nothing may follow the %YAML version except a # comment') Prevention
- Keep directives on their own single-purpose lines.
- Comments after directives must start with '#'.
- Automate header generation instead of hand-editing.
When it happens
Trigger: yaml.safe_load() on input with '%YAML 1.2 extra', '%YAML 1.1.1', '%YAML 1.1x' — anything after the minor number that is not whitespace-then-EOL/comment.
Common situations: Comments attached without '#': '%YAML 1.2 standard'; build scripts appending flags to the header line; a duplicated version token from templating.
Related errors
- expected a digit or '.', but found %r
- expected a digit, but found %r
- found incompatible YAML document (version 1.* is required)
- expected alphabetic or numeric character, but found %r
- expected ' ', but found %r
AI-assisted analysis of netdata/netdata@4864de85e2 (2026-08-15).
Data as JSON: /api/errors/5d993e002fc4408f.
Report an issue: GitHub.