Skip to content

Fix leafref path resolution under choice/case YANG nodes#234

Open
steiler wants to merge 1 commit intomainfrom
fixPathNormalizationCHoice
Open

Fix leafref path resolution under choice/case YANG nodes#234
steiler wants to merge 1 commit intomainfrom
fixPathNormalizationCHoice

Conversation

@steiler
Copy link
Copy Markdown
Collaborator

@steiler steiler commented May 5, 2026

YANG choice and case nodes are structural — they exist in the AST for conditional branching but are absent from the effective instance-data path. GetEntry() flattens through them, so any reconstructed lookup path that includes their names fails with "entry not found".

relativeToAbsPath() was walking the parent chain one step per .. token without skipping these structural nodes. For a leaf nested under choice/case ancestors, the reconstructed absolute path included those names, breaking schema initialization and live schema queries for the affected leafrefs.

Changes

  • relativeToAbsPath() — skips IsChoice()/IsCase() nodes during both the .. traversal and the upward prefix reconstruction.
  • buildReferences() and toSchemaType()GetEntry() errors now include the original leafref path and the normalized path slice for actionable diagnostics.
  • references_test.go — added:
    • Integration fixture (synthetic YANG, no vendor deps) reproducing the choice/case/list/leafref topology; verifies schema init succeeds and REF_ annotation is attached to the resolved target.
    • normalizePath() matrix covering: relative with choice/case ancestors, relative without, absolute path, module-prefixed segments.
    • Error-format assertions for both buildReferences() and toSchemaType() call paths.

Out of scope

  • No GetEntry() strip-pass for choice/case labels (would silently mask malformed paths).
  • relativeToAbsPathKeys() key-annotation fix is deferred (metadata only, not resolution correctness).
  • Absolute leafref paths that name choice/case labels are invalid YANG (RFC 7950 §9.9.5) — vendor issue.

YANG `choice` and `case` nodes are structural — they exist in the AST for
conditional branching but are absent from the effective instance-data path.
`GetEntry()` flattens through them, so any reconstructed lookup path that
includes their names fails with "entry not found".

`relativeToAbsPath()` was walking the parent chain one step per `..` token
without skipping these structural nodes. For a leaf nested under `choice`/`case`
ancestors, the reconstructed absolute path included those names, breaking schema
initialization and live schema queries for the affected leafrefs.

### Changes

- **`relativeToAbsPath()`** — skips `IsChoice()`/`IsCase()` nodes during both
  the `..` traversal and the upward prefix reconstruction.
- **`buildReferences()` and `toSchemaType()`** — `GetEntry()` errors now include
  the original leafref path and the normalized path slice for actionable
  diagnostics.
- **`references_test.go`** — added:
  - Integration fixture (synthetic YANG, no vendor deps) reproducing the
    choice/case/list/leafref topology; verifies schema init succeeds and `REF_`
    annotation is attached to the resolved target.
  - `normalizePath()` matrix covering: relative with choice/case ancestors,
    relative without, absolute path, module-prefixed segments.
  - Error-format assertions for both `buildReferences()` and `toSchemaType()`
    call paths.

### Out of scope

- No `GetEntry()` strip-pass for choice/case labels (would silently mask
  malformed paths).
- `relativeToAbsPathKeys()` key-annotation fix is deferred (metadata only, not
  resolution correctness).
- Absolute leafref paths that name choice/case labels are invalid YANG
  (RFC 7950 §9.9.5) — vendor issue.
@steiler steiler requested a review from a team as a code owner May 5, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant