OtterMind/Chat2DB · warning · BusinessException
largeCellValue.rowNotFound
largeCellValue.rowNotFound
Error message
largeCellValue.rowNotFound
What it means
Thrown while reading a chunk of a large cell value when the prepared SELECT against the source table returns no rows (resultSet.next() is false). The LargeValueReference points at a row identified by primary key, and that row no longer exists in the database at read time.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbCellValueServiceImpl.java:64
private static final int BINARY_TYPE_SAMPLE_SIZE = 64 * 1024;
private static final String TEXT_PLAIN = "text/plain";
private static final String TEXT_DOWNLOAD = "text/plain;charset=UTF-8";
private static final String APPLICATION_JSON = "application/json";
private static final String IMAGE_WILDCARD = "image/*";
@Override
public CellValueChunk readChunk(DbCellValueChunkReadRequest readCellValueChunkRequest) {
LargeValueReference reference = readCellValueChunkRequest == null ? null : readCellValueChunkRequest.getReference();
Long offsetParam = readCellValueChunkRequest == null ? null : readCellValueChunkRequest.getOffset();
Integer limitParam = readCellValueChunkRequest == null ? null : readCellValueChunkRequest.getLimit();
CellValueFormatEnum format = CellValueFormatEnum.fromRequest(
readCellValueChunkRequest == null ? null : readCellValueChunkRequest.getFormat());
long offset = Math.max(0L, offsetParam == null ? 0L : offsetParam);
int limit = normalizeLimit(limitParam, format);
try (PreparedStatement statement = prepareStatement(reference);
ResultSet resultSet = statement.executeQuery()) {
if (!resultSet.next()) {
throw new BusinessException("largeCellValue.rowNotFound");
}
Object value = resultSet.getObject(1);
int sqlType = reference.getSqlType() == null ? resultSet.getMetaData().getColumnType(1) : reference.getSqlType();
String columnType = StringUtils.defaultIfBlank(reference.getColumnType(),
resultSet.getMetaData().getColumnTypeName(1));
LargeValueTypeEnum valueType = LargeValueTypeEnum.resolveForRead(value, columnType, sqlType,
reference.getValueType());
return valueType.isBinaryLike()
? readBinaryChunk(resultSet, value, offset, limit, format, reference, valueType)
: readTextChunk(resultSet, value, offset, limit, format, reference, valueType);
} catch (SQLException | IOException e) {
throw new BusinessException("largeCellValue.readFailed", new Object[]{e.getMessage()}, e);
}
}
@Override
public CellValueDownload prepareDownload(LargeValueReference reference, String format) {
try (PreparedStatement statement = prepareStatement(reference);View on GitHub (pinned to 5ee1e990e7)
Solutions
- Instruct the user to refresh the result set and reopen the cell to obtain a fresh LargeValueReference.
- Verify the reference's primary key column(s) are populated and correct before issuing readChunk.
- If rows are volatile, shorten the window between generating the reference and reading chunks, or snapshot the row.
Defensive patterns
Strategy: try-catch
Validate before calling
// Best-effort pre-check that the source row still exists
try (PreparedStatement ps = conn.prepareStatement(
"SELECT 1 FROM " + table + " WHERE " + pkPredicate)) {
bindPk(ps, reference.getPrimaryKey());
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) {
// tell the user to refresh the result set instead of calling readChunk
}
}
} Try / catch
try {
cellValueService.readChunk(request);
} catch (BusinessException e) {
if ("largeCellValue.rowNotFound".equals(e.getCode())) {
// surface 'row no longer exists; refresh the result set' to the user
} else {
throw e;
}
} Prevention
- Invalidate cell references when the parent result set is refreshed or closed.
- Keep the window between opening a cell and reading chunks short for volatile tables.
- Disable the read UI once the result set is known to be stale.
When it happens
Trigger: readChunk() is called with a stale LargeValueReference whose primary key was deleted, the row was modified so the key no longer matches, or the underlying table/data changed between result-set generation and the chunk fetch. Concurrent deletes or a transaction visibility mismatch can also produce an empty result.
Common situations: User opens a large cell, leaves it open, then the row is deleted by another session or by a re-run of a query whose result set is now stale; reference carries a primary key that the dialect cannot round-trip.
Related errors
- largeCellValue.readFailed
- largeCellValue.downloadFailed
- largeCellValue.rowLocatorRequired
- largeCellValue.partialPreviewEditRejected
- largeCellValue.tokenRequired
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/ff3f588b6f633368.
Report an issue: GitHub.