iflytek/astron-agent · error · BusinessException

8527

8527

Error message

database.field.cannot.beyond.20

What it means

Thrown by DatabaseService.updateTable when the resulting field count after an update would exceed 20. It compares the existing field count with the number of fields marked INSERT minus fields marked DELETE in the request (line 425-430).

Solutions

  1. Reduce the number of INSERT-operated fields so the total stays <= 20
  2. Mark obsolete fields with the correct DELETE operateType so they offset the count
  3. Split columns across a second related table
  4. Verify field operateType values match DBOperateEnum codes exactly

Example fix

// before
fieldCount=15, insertCount=8, deleteCount=0 -> 23 > 20
// after
fieldCount=15, insertCount=5, deleteCount=0 -> 20 OK (or mark 3 fields as DELETE)
Defensive patterns

Strategy: validation

Validate before calling

long fieldCount = dbTableFieldMapper.selectCount(
    new QueryWrapper<DbTableField>().lambda().eq(DbTableField::getTbId, tbId));
long insertCount = dto.getFields().stream()
    .filter(f -> DBOperateEnum.INSERT.getCode().equals(f.getOperateType())).count();
long deleteCount = dto.getFields().stream()
    .filter(f -> DBOperateEnum.DELETE.getCode().equals(f.getOperateType())).count();
if (fieldCount + insertCount - deleteCount > 20) {
    throw new IllegalStateException("update would exceed 20-field limit");
}

Try / catch

try {
    databaseService.updateTable(dto);
} catch (BusinessException e) {
    if ("DATABASE_FIELD_CANNOT_BEYOND_20".equals(e.getCode())) { /* reduce inserts or mark deletions */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling updateTable with field operations where fieldCount + insertCount - deleteCount > 20, e.g. adding columns to a table that already has 18+ fields, or an update whose delete operations don't offset its inserts.

Common situations: Incrementally adding columns to a wide table until hitting the cap; a request that includes DELETE ops that the service fails to count as intended (e.g. wrong operateType value like 'remove' instead of DELETE code) making the computed count exceed 20.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/889c5b45cdffab9c. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/database/DatabaseService.java:429

                        .eq(DbTable::getDeleted, false));
                if (count > 0) {
                    throw new BusinessException(ResponseEnum.DATABASE_TABLE_NAME_EXIST);
                }
            }
            // Query table field count
            Long fieldCount = dbTableFieldMapper.selectCount(new QueryWrapper<DbTableField>().lambda()
                    .eq(DbTableField::getTbId, dbTable.getId()));
            // Count the number of new fields and deleted fields
            long insertCount = dbTableDto.getFields()
                    .stream()
                    .filter(field -> DBOperateEnum.INSERT.getCode().equals(field.getOperateType()))
                    .count();
            long deleteCount = dbTableDto.getFields()
                    .stream()
                    .filter(field -> DBOperateEnum.DELETE.getCode().equals(field.getOperateType()))
                    .count();
            if (fieldCount + insertCount - deleteCount > 20) {
                throw new BusinessException(ResponseEnum.DATABASE_FIELD_CANNOT_BEYOND_20);
            }
            DbInfo dbInfo = dbInfoMapper.selectById(dbTable.getDbId());
            if (dbTableDto.getFields() != null && !dbTableDto.getFields().isEmpty()) {
                for (DbTableFieldDto field : dbTableDto.getFields()) {
                    DbTableField dbTableField = dbTableFieldMapper.selectById(field.getId());
                    if (DBOperateEnum.INSERT.getCode().equals(field.getOperateType())) {
                        DbTableField newDbTableField = new DbTableField();
                        BeanUtils.copyProperties(field, newDbTableField);
                        newDbTableField.setTbId(dbTable.getId());
                        newDbTableField.setCreateTime(new Date());
                        newDbTableField.setUpdateTime(new Date());
                        dbTableFieldMapper.insert(newDbTableField);
                    } else if (DBOperateEnum.UPDATE.getCode().equals(field.getOperateType())) {
                        BeanUtils.copyProperties(field, dbTableField);
                        dbTableField.setUpdateTime(new Date());
                        dbTableFieldMapper.updateById(dbTableField);
                    } else if (DBOperateEnum.DELETE.getCode().equals(field.getOperateType())) {
                        dbTableFieldMapper.deleteById(field.getId());

View on GitHub (pinned to 5e758547a8)