OtterMind/Chat2DB · warning · BusinessException
largeCellValue.tokenExpired
largeCellValue.tokenExpired
Error message
largeCellValue.tokenExpired
What it means
Thrown by DbLargeValueTokenServiceImpl.requireValid when tokenCache.get(id) returns null. LargeValueTokens live in an in-memory cache (tokenCache); a miss means the token was never issued, was evicted, or the process restarted and lost it. Resolves to 'This large value reference has expired. Refresh the result set and reopen this cell.' This is a recoverable, transient condition, not a hard failure.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbLargeValueTokenServiceImpl.java:83
cell.setUnsupportedReason(UNSUPPORTED_REASON_KEY);
continue;
}
LargeValueToken token = createToken(dataSourceId, databaseName, schemaName, tableName,
columnName, primaryKey, cell);
tokenCache.put(token.getId(), token);
cell.setLargeValueId(token.getId());
}
}
}
@Override
public LargeValueToken requireValid(String id) {
if (StringUtils.isBlank(id)) {
throw new BusinessException("largeCellValue.tokenRequired");
}
LargeValueToken token = tokenCache.get(id);
if (token == null) {
throw new BusinessException("largeCellValue.tokenExpired");
}
if (Instant.now().isAfter(token.getExpiresAt())) {
tokenCache.remove(id);
throw new BusinessException("largeCellValue.tokenExpired");
}
validateOwner(token);
return token;
}
private void cleanupExpired() {
Instant now = Instant.now();
tokenCache.entrySet().removeIf(entry -> now.isAfter(entry.getValue().getExpiresAt()));
}
private Map<Integer, Header> getPrimaryKeyHeaders(List<Header> headers) {
Map<Integer, Header> primaryKeyHeaders = new LinkedHashMap<>();
for (int i = 0; i < headers.size(); i++) {
Header header = headers.get(i);View on GitHub (pinned to 5ee1e990e7)
Solutions
- Refresh the source result set so tokens are re-issued, then reopen the cell.
- If running multi-instance, pin large-value fetches to the instance that rendered the result set, or move token state to a shared store.
- Increase token TTL/cache capacity if evictions are frequent.
Defensive patterns
Strategy: retry
Try / catch
try {
tokenService.requireValid(id);
} catch (BusinessException e) { // largeCellValue.tokenExpired
// re-render the result set to re-issue tokens, then retry once
} Prevention
- Refresh the result set before reading long-idle large cells.
- Pin large-value requests to the rendering instance in multi-node setups.
- Tune token TTL/cache size to the session length.
When it happens
Trigger: Requesting a large value after the backend restarted (cache cleared); after the token TTL/capacity eviction ran; or with an id that was fabricated/never issued by this process. Any of these yield a null cache entry.
Common situations: Long-lived UI session where the user left a large cell open across a restart; horizontal scaling where the request lands on a different instance that does not hold the token; cache eviction under memory pressure.
Related errors
- largeCellValue.tokenRequired
- largeCellValue.tokenForbidden
- largeCellValue.rowNotFound
- largeCellValue.readFailed
- largeCellValue.downloadFailed
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/277e6e9437128c7e.
Report an issue: GitHub.