Skip to content

EventsCompactionConfig.compaction_interval accepts 0/negative, silently compacting on every invocation #6397

Description

@hiroakis

🔴 Required Information

Describe the Bug:
EventsCompactionConfig.compaction_interval and overlap_size are declared as plain required ints with no value constraints, unlike their sibling fields token_threshold (Field(gt=0)) and event_retention_size (Field(ge=0)).

As a result, compaction_interval=0 (or a negative value) is silently accepted and makes the sliding-window compaction trigger fire on every invocation. In _run_compaction_for_sliding_window (src/google/adk/apps/compaction.py) the guard

if len(new_invocation_ids) < config.compaction_interval:
    return None  # Not enough new invocations to trigger compaction.

can never be true when compaction_interval <= 0, so compaction runs after every invocation instead of being throttled.

This is also confusing because 0 means different things for the two sliding-window fields: overlap_size=0 is a valid "no overlap", but compaction_interval=0 is a degenerate "fire every time" (not "disable").

Steps to Reproduce:

  1. pip install google-adk
  2. Run the snippet below (or construct an App with events_compaction_config=EventsCompactionConfig(compaction_interval=0, overlap_size=0, summarizer=...)).
  3. Observe that construction succeeds with compaction_interval=0.
  4. With such a config, sliding-window compaction fires on every invocation.

Expected Behavior:
compaction_interval=0 (and negative values) should be rejected at construction time with a ValidationError, consistent with token_threshold (gt=0) and event_retention_size (ge=0). overlap_size should allow 0 (no overlap) but reject negatives.

Observed Behavior:
EventsCompactionConfig(compaction_interval=0, overlap_size=0) is accepted with no error, and downstream causes compaction to run on every invocation.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.4.0
  • Desktop OS: macOS
  • Python Version (python -V): 3.10

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A (configuration-validation bug, model-agnostic)

🟡 Optional Information

Regression:
N/A — appears to have been present since EventsCompactionConfig was introduced.

Additional Context:
Suggested fix (small, mirrors the existing validated sibling fields):

  • compaction_interval: int = Field(gt=0)
  • overlap_size: int = Field(ge=0) (0 = no overlap, still valid)

Happy to send a PR with tests.

Separately (tracked as a feature request, not this bug): because compaction_interval / overlap_size are required, there is currently no clean way to enable only the token-threshold trigger without setting compaction_interval to a large sentinel value.

Minimal Reproduction Code:

from google.adk.apps.app import EventsCompactionConfig

# Accepted today (no error); makes sliding-window compaction fire every invocation.
cfg = EventsCompactionConfig(compaction_interval=0, overlap_size=0)
print(cfg.compaction_interval)  # -> 0

# Negative is also accepted today.
EventsCompactionConfig(compaction_interval=-1, overlap_size=0)

How often has this issue occurred?:

  • Always (100%)

Metadata

Metadata

Labels

core[Component] This issue is related to the core interface and implementation

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions