Skip to content

feat: cap slog group nesting depth at 10 levels#26

Merged
ankurs merged 3 commits intomainfrom
feat/bound-slog-group-depth
Apr 9, 2026
Merged

feat: cap slog group nesting depth at 10 levels#26
ankurs merged 3 commits intomainfrom
feat/bound-slog-group-depth

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented Apr 9, 2026

Summary

  • Add depth parameter to appendAttr() to prevent unbounded recursion from pathological nested slog group attributes
  • Groups beyond depth 10 are replaced with [nested group depth exceeded] placeholder
  • Addresses ROADMAP item 2.4

Test plan

  • TestAppendAttr_DeepNesting verifies 15-level nesting is capped at 10
  • All existing slog bridge tests pass
  • make test and make lint clean

Summary by CodeRabbit

  • Bug Fixes

    • Added a cap on nested log attribute expansion; overly deep groups are replaced with a placeholder "[nested group depth exceeded]" to avoid infinite recursion and processing issues.
  • Tests

    • Added coverage for extreme nesting to validate the depth limit and placeholder behavior.
  • Chores

    • Updated Go toolchain directive to 1.25.9.

Add depth parameter to appendAttr() to prevent unbounded recursion
from pathological nested slog group attributes. Groups beyond depth 10
are replaced with a placeholder value.
Copilot AI review requested due to automatic review settings April 9, 2026 05:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Adds a recursion depth parameter to attribute flattening in the slog wrapper and enforces a max group nesting limit; deeply nested groups are replaced with a placeholder instead of being expanded.

Changes

Cohort / File(s) Summary
Slog wrapper logic
wrap/slogwrap.go
appendAttr now accepts a depth int and caller sites pass 0. Tracks recursion depth, caps expansion at maxGroupDepth, and appends "[nested group depth exceeded]" when exceeded; recursive calls use depth+1.
Tests
wrap/slogwrap_test.go
Added TestAppendAttr_DeepNesting that builds a deeply nested slog.Group (beyond maxGroupDepth) and asserts the placeholder is emitted and the deep leaf value is not expanded.
Go toolchain
go.mod
Bumped go directive from 1.25.8 to 1.25.9 (module toolchain version update).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I dug through groups, one, two, three,
Deeper and deeper — oh dear me!
At ten I pause, I thump my foot,
"No more peeking," says my root.
A placeholder hops in where depths exceed.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: capping slog group nesting depth at 10 levels, which is the core feature implemented across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bound-slog-group-depth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a safety cap to the slog bridge attribute flattener to avoid unbounded recursion when handling pathologically deep nested slog group attributes.

Changes:

  • Add maxGroupDepth and a depth parameter to appendAttr to cap nested slog group recursion at 10 levels.
  • Emit a "[nested group depth exceeded]" placeholder when the depth cap is hit.
  • Add TestAppendAttr_DeepNesting to verify deep nesting is capped.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
wrap/slogwrap.go Implements a max nesting depth check when flattening slog group attributes.
wrap/slogwrap_test.go Adds coverage to ensure deep nested groups are capped and a placeholder is emitted.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
wrap/slogwrap.go (1)

129-150: Extract the depth-exceeded placeholder into a shared constant.

The placeholder text is duplicated between implementation and tests. A shared constant avoids drift if wording changes later.

♻️ Proposed refactor
-const maxGroupDepth = 10
+const (
+	maxGroupDepth                    = 10
+	nestedGroupDepthExceededMessage = "[nested group depth exceeded]"
+)
@@
 		if depth >= maxGroupDepth {
-			return append(args, key, "[nested group depth exceeded]")
+			return append(args, key, nestedGroupDepthExceededMessage)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wrap/slogwrap.go` around lines 129 - 150, The placeholder string "[nested
group depth exceeded]" is duplicated; extract it into a shared constant (e.g.,
groupDepthExceededPlaceholder) and use it in appendAttr (which checks depth
against maxGroupDepth) instead of the inline literal; update any tests that
assert this message to reference the new constant so wording stays synchronized,
and ensure the constant is exported or placed in a package-accessible location
used by both the implementation and tests.
wrap/slogwrap_test.go (1)

411-458: Add explicit boundary tests at the cutoff (10 and 11 levels).

This test is great for pathological depth, but adding exact-threshold cases will better guard against off-by-one regressions around maxGroupDepth.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wrap/slogwrap_test.go` around lines 411 - 458, Add two explicit unit tests
around the grouping cutoff: one that builds exactly maxGroupDepth levels (should
NOT produce the "[nested group depth exceeded]" placeholder and should resolve
the leaf) and one that builds maxGroupDepth+1 levels (should produce the
placeholder and should NOT resolve the full deep leaf). Reuse the same pattern
as TestAppendAttr_DeepNesting (create nested slog.Group chains, create a
slog.Record, call ToSlogHandler(h).Handle, inspect cl.lastEntry().Args) but
construct one tree of depth equal to maxGroupDepth and another of depth equal to
maxGroupDepth+1; assert presence/absence of the placeholder and that the leaf
resolution behavior matches expectations. Ensure tests reference the handler
conversion flow (ToSlogHandler, Handle) and the same placeholder string "[nested
group depth exceeded]" so they guard off-by-one regressions around the
maxGroupDepth cutoff.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@wrap/slogwrap_test.go`:
- Around line 411-458: Add two explicit unit tests around the grouping cutoff:
one that builds exactly maxGroupDepth levels (should NOT produce the "[nested
group depth exceeded]" placeholder and should resolve the leaf) and one that
builds maxGroupDepth+1 levels (should produce the placeholder and should NOT
resolve the full deep leaf). Reuse the same pattern as
TestAppendAttr_DeepNesting (create nested slog.Group chains, create a
slog.Record, call ToSlogHandler(h).Handle, inspect cl.lastEntry().Args) but
construct one tree of depth equal to maxGroupDepth and another of depth equal to
maxGroupDepth+1; assert presence/absence of the placeholder and that the leaf
resolution behavior matches expectations. Ensure tests reference the handler
conversion flow (ToSlogHandler, Handle) and the same placeholder string "[nested
group depth exceeded]" so they guard off-by-one regressions around the
maxGroupDepth cutoff.

In `@wrap/slogwrap.go`:
- Around line 129-150: The placeholder string "[nested group depth exceeded]" is
duplicated; extract it into a shared constant (e.g.,
groupDepthExceededPlaceholder) and use it in appendAttr (which checks depth
against maxGroupDepth) instead of the inline literal; update any tests that
assert this message to reference the new constant so wording stays synchronized,
and ensure the constant is exported or placed in a package-accessible location
used by both the implementation and tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2aeaf92a-c5d1-49a0-8f39-063e060aeca0

📥 Commits

Reviewing files that changed from the base of the PR and between 8b3e312 and 983c2e7.

📒 Files selected for processing (2)
  • wrap/slogwrap.go
  • wrap/slogwrap_test.go

… bump Go 1.25.9

Address review: extract GroupDepthExceededPlaceholder const to avoid
duplicated string literal. Derive test nesting depth from maxGroupDepth
so the test adapts if the cap changes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Address review: make groupDepthExceededPlaceholder unexported (not part
of public API). Assert leaf value doesn't appear at all when nesting
exceeds cap, not just at full depth.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
wrap/slogwrap_test.go (1)

411-454: Strengthen boundary assertion to catch off-by-one depth regressions.

Current checks confirm truncation happened, but not where it happened. Adding an expected placeholder key assertion would lock in the exact cap boundary.

Proposed test hardening
 func TestAppendAttr_DeepNesting(t *testing.T) {
@@
 	foundPlaceholder := false
+	foundPlaceholderAtExpectedKey := false
 	foundLeafValue := false
@@
+	expectedParts := make([]string, maxGroupDepth+1)
+	for i := 0; i <= maxGroupDepth; i++ {
+		expectedParts[i] = fmt.Sprintf("g%d", i)
+	}
+	expectedPlaceholderKey := strings.Join(expectedParts, ".")
+
 	for i := start; i < len(entry.Args)-1; i += 2 {
+		k, _ := entry.Args[i].(string)
 		v := fmt.Sprint(entry.Args[i+1])
 		if v == groupDepthExceededPlaceholder {
 			foundPlaceholder = true
+			if k == expectedPlaceholderKey {
+				foundPlaceholderAtExpectedKey = true
+			}
 		}
 		if v == "deep" {
 			foundLeafValue = true
 		}
 	}
@@
 	if !foundPlaceholder {
 		t.Errorf("expected depth-exceeded placeholder in args, got: %v", entry.Args)
 	}
+	if !foundPlaceholderAtExpectedKey {
+		t.Errorf("expected placeholder at key %q, got: %v", expectedPlaceholderKey, entry.Args)
+	}
 	if foundLeafValue {
 		t.Errorf("leaf value should not appear when nesting exceeds maxGroupDepth (%d), got: %v", maxGroupDepth, entry.Args)
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wrap/slogwrap_test.go` around lines 411 - 454, TestAppendAttr_DeepNesting
currently only asserts that a depth-exceeded placeholder appears and the leaf
value is absent; strengthen it by asserting the placeholder occurs exactly at
the expected group boundary. In the TestAppendAttr_DeepNesting test, after
building the nested groups and getting entry.Args, locate the pair where the
value equals groupDepthExceededPlaceholder and assert the corresponding key
equals fmt.Sprintf("g%d", maxGroupDepth) (use maxGroupDepth and
groupDepthExceededPlaceholder to compute expected key/value); keep the existing
assertion that "deep" does not appear. This ensures the truncation happens at
the exact cap and will catch off-by-one regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@wrap/slogwrap_test.go`:
- Around line 411-454: TestAppendAttr_DeepNesting currently only asserts that a
depth-exceeded placeholder appears and the leaf value is absent; strengthen it
by asserting the placeholder occurs exactly at the expected group boundary. In
the TestAppendAttr_DeepNesting test, after building the nested groups and
getting entry.Args, locate the pair where the value equals
groupDepthExceededPlaceholder and assert the corresponding key equals
fmt.Sprintf("g%d", maxGroupDepth) (use maxGroupDepth and
groupDepthExceededPlaceholder to compute expected key/value); keep the existing
assertion that "deep" does not appear. This ensures the truncation happens at
the exact cap and will catch off-by-one regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d249278-077f-4c14-9c09-2eeeff4e89ab

📥 Commits

Reviewing files that changed from the base of the PR and between 983c2e7 and 8532508.

📒 Files selected for processing (3)
  • go.mod
  • wrap/slogwrap.go
  • wrap/slogwrap_test.go
✅ Files skipped from review due to trivial changes (1)
  • go.mod

@ankurs ankurs merged commit a80f7ca into main Apr 9, 2026
8 checks passed
@ankurs ankurs deleted the feat/bound-slog-group-depth branch April 9, 2026 07:19
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.

2 participants