spring-projects/spring-ai · error · IllegalArgumentException

Either TTL or expire time must be set for update

Error message

Either TTL or expire time must be set for update

What it means

CachedContentUpdateRequest.build() enforces that an update to cached content changes its expiration: at least one of ttl or expireTime must be set, otherwise IllegalArgumentException is thrown. Gemini's cachedContent update API requires an expiration change.

Source

Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/cache/CachedContentUpdateRequest.java:82

		@Nullable private Instant expireTime;

		private Builder() {
		}

		public Builder ttl(Duration ttl) {
			this.ttl = ttl;
			return this;
		}

		public Builder expireTime(Instant expireTime) {
			this.expireTime = expireTime;
			return this;
		}

		public CachedContentUpdateRequest build() {
			if (this.ttl == null && this.expireTime == null) {
				throw new IllegalArgumentException("Either TTL or expire time must be set for update");
			}
			return new CachedContentUpdateRequest(this);
		}

	}

}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Set a TTL, e.g. builder.ttl(Duration.ofHours(2)).build().
  2. Or set an absolute expireTime, e.g. builder.expireTime(Instant.now().plus(Duration.ofDays(1))).build().
  3. If no expiration change is desired, skip the update call entirely (the API only supports updating expiration).
  4. Validate that at least one expiration field is non-null before building in your service layer.

Example fix

// before
new CachedContentUpdateRequest.Builder().build(); // throws
// after
new CachedContentUpdateRequest.Builder().ttl(Duration.ofHours(2)).build();
Defensive patterns

Strategy: validation

Validate before calling

if (ttl == null && expireTime == null) {
    throw new IllegalStateException("set ttl or expireTime before building CachedContentUpdateRequest");
}

Try / catch

try { req.build(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("TTL or expire time")) setDefaultTtl(); else throw e; }

Prevention

When it happens

Trigger: Calling builder.build() with neither .ttl(...) nor .expireTime(...) set, then submitting the update for a cached content resource.

Common situations: Copying update-request code that previously set expiration; conditionally setting expiration values where both branches evaluated to null; intending to update other fields but the API only supports expiration updates.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/76e32da2608491fb. Report an issue: GitHub.