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

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions