{"record":{"id":"889c5b45cdffab9c","repo":"iflytek/astron-agent","slug":"8527-database-field-cannot-beyond-20","errorCode":"8527","errorMessage":"database.field.cannot.beyond.20","messagePattern":"database\\.field\\.cannot\\.beyond\\.20","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/database/DatabaseService.java","lineNumber":429,"sourceCode":"                        .eq(DbTable::getDeleted, false));\n                if (count > 0) {\n                    throw new BusinessException(ResponseEnum.DATABASE_TABLE_NAME_EXIST);\n                }\n            }\n            // Query table field count\n            Long fieldCount = dbTableFieldMapper.selectCount(new QueryWrapper<DbTableField>().lambda()\n                    .eq(DbTableField::getTbId, dbTable.getId()));\n            // Count the number of new fields and deleted fields\n            long insertCount = dbTableDto.getFields()\n                    .stream()\n                    .filter(field -> DBOperateEnum.INSERT.getCode().equals(field.getOperateType()))\n                    .count();\n            long deleteCount = dbTableDto.getFields()\n                    .stream()\n                    .filter(field -> DBOperateEnum.DELETE.getCode().equals(field.getOperateType()))\n                    .count();\n            if (fieldCount + insertCount - deleteCount > 20) {\n                throw new BusinessException(ResponseEnum.DATABASE_FIELD_CANNOT_BEYOND_20);\n            }\n            DbInfo dbInfo = dbInfoMapper.selectById(dbTable.getDbId());\n            if (dbTableDto.getFields() != null && !dbTableDto.getFields().isEmpty()) {\n                for (DbTableFieldDto field : dbTableDto.getFields()) {\n                    DbTableField dbTableField = dbTableFieldMapper.selectById(field.getId());\n                    if (DBOperateEnum.INSERT.getCode().equals(field.getOperateType())) {\n                        DbTableField newDbTableField = new DbTableField();\n                        BeanUtils.copyProperties(field, newDbTableField);\n                        newDbTableField.setTbId(dbTable.getId());\n                        newDbTableField.setCreateTime(new Date());\n                        newDbTableField.setUpdateTime(new Date());\n                        dbTableFieldMapper.insert(newDbTableField);\n                    } else if (DBOperateEnum.UPDATE.getCode().equals(field.getOperateType())) {\n                        BeanUtils.copyProperties(field, dbTableField);\n                        dbTableField.setUpdateTime(new Date());\n                        dbTableFieldMapper.updateById(dbTableField);\n                    } else if (DBOperateEnum.DELETE.getCode().equals(field.getOperateType())) {\n                        dbTableFieldMapper.deleteById(field.getId());","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/database/DatabaseService.java#L411-L447","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reduce the number of INSERT-operated fields so the total stays <= 20","Mark obsolete fields with the correct DELETE operateType so they offset the count","Split columns across a second related table","Verify field operateType values match DBOperateEnum codes exactly"],"exampleFix":"// before\nfieldCount=15, insertCount=8, deleteCount=0 -> 23 > 20\n// after\nfieldCount=15, insertCount=5, deleteCount=0 -> 20 OK (or mark 3 fields as DELETE)","handlingStrategy":"validation","validationCode":"long fieldCount = dbTableFieldMapper.selectCount(\n    new QueryWrapper<DbTableField>().lambda().eq(DbTableField::getTbId, tbId));\nlong insertCount = dto.getFields().stream()\n    .filter(f -> DBOperateEnum.INSERT.getCode().equals(f.getOperateType())).count();\nlong deleteCount = dto.getFields().stream()\n    .filter(f -> DBOperateEnum.DELETE.getCode().equals(f.getOperateType())).count();\nif (fieldCount + insertCount - deleteCount > 20) {\n    throw new IllegalStateException(\"update would exceed 20-field limit\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    databaseService.updateTable(dto);\n} catch (BusinessException e) {\n    if (\"DATABASE_FIELD_CANNOT_BEYOND_20\".equals(e.getCode())) { /* reduce inserts or mark deletions */ }\n    throw e;\n}","preventionTips":["Track field counts per table and warn users near the 20-column cap","Always use exact DBOperateEnum codes for operateType so deletes are counted","Redesign wide tables into normalized multiple tables"],"tags":["database","limit","update"],"backgroundTag":"value-out-of-range","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}