OtterMind/Chat2DB · warning · BusinessException

largeCellValue.partialPreviewEditRejected

largeCellValue.partialPreviewEditRejected

Error message

largeCellValue.partialPreviewEditRejected

What it means

Thrown by rejectPartialLargeValueOperations when any ResultOperation in a DbSelectResultUpdateRequest contains a cell value (in dataList or oldDataList) starting with the prefix 'CHAT2DB_LARGE_VALUE_PREVIEW:'. Large cell values are stored server-side and replaced with preview tokens in partial result sets; editing a row that includes such a placeholder is rejected because the full value was never sent to the client and cannot be safely written back.

Solutions

  1. Fetch the full large value for the cell before editing (resolve the token via the large-value-token API).
  2. Exclude rows containing large-value placeholders from the edit batch.
  3. Increase the preview threshold or fetch full results if editing large values is required.

Example fix

// before
updateSelectResult(DbSelectResultUpdateRequest.builder()
    .operations(List.of(ResultOperation.builder()
        .dataList(List.of("CHAT2DB_LARGE_VALUE_PREVIEW:abc123", "newval"))
        .build()))
    .build()); // -> partialPreviewEditRejected

// after
// resolve the token to the full value first, or exclude this row
updateSelectResult(DbSelectResultUpdateRequest.builder()
    .operations(List.of(ResultOperation.builder()
        .dataList(List.of(fullResolvedValue, "newval"))
        .build()))
    .build());
Defensive patterns

Strategy: validation

Validate before calling

private static final String LARGE_VALUE_PREVIEW_PREFIX = "CHAT2DB_LARGE_VALUE_PREVIEW:";
boolean hasPlaceholder = request.getOperations().stream()
    .anyMatch(op -> containsPrefix(op.getDataList()) || containsPrefix(op.getOldDataList()));
// where containsPrefix checks any cell startsWith(LARGE_VALUE_PREVIEW_PREFIX)
if (hasPlaceholder) { /* resolve tokens or exclude rows before update */ }

Type guard

boolean rowIsEditable(List<String> row) {
    return row == null || row.stream().noneMatch(v -> v != null && v.startsWith("CHAT2DB_LARGE_VALUE_PREVIEW:"));
}

Prevention

When it happens

Trigger: Calling rejectPartialLargeValueOperations (or a select-result update that delegates to it) where at least one operation's dataList or oldDataList entry starts with 'CHAT2DB_LARGE_VALUE_PREVIEW:'. This happens when a query result was paginated/truncated and a large cell was replaced by a token.

Common situations: User edits a row in a result set where a LOB/CLOB/TEXT column exceeded the preview threshold and was replaced by a token; frontend submits a partial-preview row for update without first fetching the full value; bulk-edit operation includes a row with a truncated large value.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/40308e9c928933c5. Report an issue: GitHub.

Appendix: source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDmlExecutionServiceImpl.java:89

            if (result != null) {
                sqlOperationLogRecorder.recordResultAsync(result, request.getSource());
            }
            return result;
        } catch (RuntimeException e) {
            sqlOperationLogRecorder.recordFailureAsync(executeRequest.getSql(), request.getSource(), e.getMessage());
            throw e;
        }
    }

    @Override
    public void rejectPartialLargeValueOperations(DbSelectResultUpdateRequest request) {
        if (request == null || CollectionUtils.isEmpty(request.getOperations())) {
            return;
        }
        for (ResultOperation operation : request.getOperations()) {
            if (containsLargeValuePlaceholder(operation.getDataList())
                    || containsLargeValuePlaceholder(operation.getOldDataList())) {
                throw new BusinessException("largeCellValue.partialPreviewEditRejected");
            }
        }
    }

    private List<ExecuteResponse> executeAndRecord(DbDmlExecutionRequest request,
            ExecuteFunction executeFunction) {
        boolean operationLogged = false;
        DbDlExecuteRequest executeRequest = requireExecuteRequest(request);
        try {
            List<ExecuteResponse> results = executeFunction.execute(executeRequest);
            sqlOperationLogRecorder.recordResultsAsync(results, request.getSource());
            operationLogged = true;
            attachLargeValueTokens(executeRequest, results);
            return results;
        } catch (RuntimeException e) {
            recordFailureIfNeeded(executeRequest, request.getSource(), operationLogged, e);
            throw e;
        }

View on GitHub (pinned to 5ee1e990e7)