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
- Set a TTL, e.g. builder.ttl(Duration.ofHours(2)).build().
- Or set an absolute expireTime, e.g. builder.expireTime(Instant.now().plus(Duration.ofDays(1))).build().
- If no expiration change is desired, skip the update call entirely (the API only supports updating expiration).
- 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
- Always chain .ttl() or .expireTime() in builder helpers
- Remember cached-content updates only change expiration
- Unit-test cache update builders for required fields
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
- ThinkingLevel.%s is not supported for model '%s'. This model
- ThinkingLevel.%s is not supported for model '%s'. Supported
- Resource URI resolves outside the cache directory:
- SSE connection '<connectionName>' requires a 'url' property.
- Incomplete Google GenAI configuration: Provide 'api-key' for
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/76e32da2608491fb.
Report an issue: GitHub.