Version
hier-config 3.4.1
Platform
Platform.CISCO_XR
Error
DuplicateChildError: Found a duplicate section: ('flow exporter-map EXPORTER1', 'route-policy POLICY1', 'endif')
Minimal Reproduction
from hier_config import get_hconfig, Platform
text = '''flow exporter-map EXPORTER1
version v9
template timeout 60
!
transport udp 9999
!
route-policy POLICY1
if (destination in PREFIX-SET1) then
drop
endif
if (destination in PREFIX-SET2) then
done
endif
drop
end-policy
!
'''
get_hconfig(Platform.CISCO_XR, text)
Stack trace:
File ".../hier_config/base.py", line 86, in add_child
raise DuplicateChildError(message)
hier_config.exceptions.DuplicateChildError: Found a duplicate section: ('flow exporter-map EXPORTER1', 'route-policy POLICY1', 'endif')
Root Cause Analysis
The IOS-XR driver defines an indent_adjust rule in hier_config/platforms/cisco_xr/driver.py (lines 106–110):
start_expression="^\s*template" → increments indent_adjust by 1
end_expression="^\s*end-template" → decrements it back
In flow exporter-map blocks, IOS-XR uses template timeout 60 as a leaf parameter — it is not a block opener and has no matching end-template. When the parser encounters this line:
indent_adjust is incremented to +1.
- No
end-template ever follows, so indent_adjust is permanently stuck at +1 for the remainder of the file.
- All subsequent top-level blocks (
route-policy POLICY1, etc.) are parsed as if they are children of the last open block (flow exporter-map EXPORTER1).
parent_allows_duplicate_child only permits duplicates when the direct parent starts with "route-policy" — but the parent is now flow exporter-map EXPORTER1, so endif appearing twice raises DuplicateChildError.
Suggested Fix Options
Option 1 — Narrow the start_expression to exclude template timeout (and similar leaf forms):
start_expression=r"^\s*template(?!\s+timeout)"
This uses a negative lookahead so lines like template timeout 60 no longer trigger the indent increment.
Option 2 — Scope the rule so it only fires when the current parent context is a template block:
Require the enclosing parent to be a template definition before bumping indent_adjust, avoiding false positives from leaf uses of the template keyword in other block types.
Driver File
hier_config/platforms/cisco_xr/driver.py, lines 106–110
Version
hier-config 3.4.1
Platform
Platform.CISCO_XRError
Minimal Reproduction
Stack trace:
Root Cause Analysis
The IOS-XR driver defines an
indent_adjustrule inhier_config/platforms/cisco_xr/driver.py(lines 106–110):start_expression="^\s*template"→ incrementsindent_adjustby 1end_expression="^\s*end-template"→ decrements it backIn
flow exporter-mapblocks, IOS-XR usestemplate timeout 60as a leaf parameter — it is not a block opener and has no matchingend-template. When the parser encounters this line:indent_adjustis incremented to +1.end-templateever follows, soindent_adjustis permanently stuck at +1 for the remainder of the file.route-policy POLICY1, etc.) are parsed as if they are children of the last open block (flow exporter-map EXPORTER1).parent_allows_duplicate_childonly permits duplicates when the direct parent starts with"route-policy"— but the parent is nowflow exporter-map EXPORTER1, soendifappearing twice raisesDuplicateChildError.Suggested Fix Options
Option 1 — Narrow the start_expression to exclude
template timeout(and similar leaf forms):This uses a negative lookahead so lines like
template timeout 60no longer trigger the indent increment.Option 2 — Scope the rule so it only fires when the current parent context is a
templateblock:Require the enclosing parent to be a
templatedefinition before bumpingindent_adjust, avoiding false positives from leaf uses of thetemplatekeyword in other block types.Driver File
hier_config/platforms/cisco_xr/driver.py, lines 106–110