Skip to content

Fix infinite cycles in configuration includes/extends#775

Merged
jviotti merged 3 commits intomainfrom
config-fixes
Mar 25, 2026
Merged

Fix infinite cycles in configuration includes/extends#775
jviotti merged 3 commits intomainfrom
config-fixes

Conversation

@jviotti
Copy link
Member

@jviotti jviotti commented Mar 25, 2026

Signed-off-by: Juan Cruz Viotti jv@jviotti.com

Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
@augmentcode
Copy link

augmentcode bot commented Mar 25, 2026

🤖 Augment PR Summary

Summary: This PR prevents infinite recursion when configuration files reference each other through extends and include.

Changes:

  • Adds ConfigurationCyclicReferenceError to report circular configuration references with from/to paths and a JSON Pointer location
  • Tracks visited configuration targets during dereferencing to detect cycles and fail fast
  • Updates the CLI entry point to print a dedicated error message for cyclic references
  • Adds unit tests + stub fixtures covering circular extends and circular include cases

Technical Notes: Target paths are normalized via weakly_canonical during resolution and the error surfaces the exact configuration pointer where the cycle is detected.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

entry.to_string()),
"one.json")};
const auto new_location{location.concat({"extends"})};
if (!visited.emplace(target_path.native()).second) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a single visited set for the whole traversal will treat any repeated include/extend of the same file as a “circular reference”, even when the dependency graph is acyclic (e.g., two branches both extend/include a shared file). That can reject valid configurations and the thrown ConfigurationCyclicReferenceError becomes misleading (it’s “already seen” rather than “in the current reference chain”).

Severity: medium

Other Locations
  • src/configuration/read.cc:100

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


dereference(collections_path, configuration_path, data, {});
std::unordered_set<std::string> visited;
visited.emplace(configuration_path.native());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visited is seeded with configuration_path.native(), but targets are inserted as weakly_canonical(...) paths; if the initial configuration_path isn’t already canonicalized (e.g., contains .. or different lexical form), a cycle back to the root may not be detected. In that case the original infinite recursion could still occur for callers that don’t canonicalize before calling Configuration::read.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/configuration/read.cc">

<violation number="1" location="src/configuration/read.cc:70">
P2: `visited` is treated as global state without being cleared on return, so reusing the same include/extends target in different branches will now throw a cyclic-reference error even when there is no cycle. Track only the current recursion stack or remove the path after the recursive call completes.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark Index (community)

Details
Benchmark suite Current: 2d63a7f Previous: 5f7a697 Ratio
Add one schema (0 existing) 21 ms 19 ms 1.11
Add one schema (100 existing) 26 ms 24 ms 1.08
Add one schema (1000 existing) 84 ms 68 ms 1.24
Add one schema (10000 existing) 691 ms 563 ms 1.23
Update one schema (1 existing) 19 ms 18 ms 1.06
Update one schema (101 existing) 28 ms 25 ms 1.12
Update one schema (1001 existing) 84 ms 74 ms 1.14
Update one schema (10001 existing) 713 ms 595 ms 1.20
Cached rebuild (1 existing) 11 ms 10 ms 1.10
Cached rebuild (101 existing) 13 ms 12 ms 1.08
Cached rebuild (1001 existing) 31 ms 24 ms 1.29
Cached rebuild (10001 existing) 234 ms 178 ms 1.31
Index 100 schemas 116 ms 157 ms 0.74
Index 1000 schemas 1040 ms 1213 ms 0.86
Index 10000 schemas 13740 ms 14280 ms 0.96

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark Index (enterprise)

Details
Benchmark suite Current: 2d63a7f Previous: 5f7a697 Ratio
Add one schema (0 existing) 23 ms 23 ms 1
Add one schema (100 existing) 27 ms 27 ms 1
Add one schema (1000 existing) 75 ms 77 ms 0.97
Add one schema (10000 existing) 693 ms 619 ms 1.12
Update one schema (1 existing) 21 ms 27 ms 0.78
Update one schema (101 existing) 27 ms 28 ms 0.96
Update one schema (1001 existing) 76 ms 77 ms 0.99
Update one schema (10001 existing) 610 ms 635 ms 0.96
Cached rebuild (1 existing) 13 ms 12 ms 1.08
Cached rebuild (101 existing) 14 ms 14 ms 1
Cached rebuild (1001 existing) 29 ms 29 ms 1
Cached rebuild (10001 existing) 199 ms 208 ms 0.96
Index 100 schemas 122 ms 123 ms 0.99
Index 1000 schemas 1095 ms 1104 ms 0.99
Index 10000 schemas 14413 ms 15256 ms 0.94

This comment was automatically generated by workflow using github-action-benchmark.

jviotti added 2 commits March 25, 2026 10:10
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
@jviotti jviotti merged commit fc61f15 into main Mar 25, 2026
6 checks passed
@jviotti jviotti deleted the config-fixes branch March 25, 2026 14:32
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