elunez/eladmin · warning · BadRequestException
A new role cannot already have an ID
Error message
A new role cannot already have an ID
What it means
Thrown by RoleController.createRole (line 98) when POST /api/roles carries a non-null id. Roles follow the same eladmin create contract; additionally this controller orders the guard before checkLevel and roleService.create, so an id-bearing body fails with 400 regardless of the level field.
Source
Thrown at eladmin-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java:98
@GetMapping
@PreAuthorize("@el.check('roles:list')")
public ResponseEntity<PageResult<RoleDto>> queryRole(RoleQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(roleService.queryAll(criteria,pageable),HttpStatus.OK);
}
@ApiOperation("获取用户级别")
@GetMapping(value = "/level")
public ResponseEntity<Object> getRoleLevel(){
return new ResponseEntity<>(Dict.create().set("level", getLevels()),HttpStatus.OK);
}
@Log("新增角色")
@ApiOperation("新增角色")
@PostMapping
@PreAuthorize("@el.check('roles:add')")
public ResponseEntity<Object> createRole(@Validated @RequestBody Role resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
checkLevel(resources.getLevel());
roleService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改角色")
@ApiOperation("修改角色")
@PutMapping
@PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Object> updateRole(@Validated(Role.Update.class) @RequestBody Role resources){
RoleDto role = roleService.findById(resources.getId());
checkLevel(role.getLevel());
checkLevel(resources.getLevel());
roleService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
View on GitHub (pinned to 55fbf70595)
Solutions
- Strip id (and menus if cloning is undesired) before POST /api/roles.
- For role cloning, build a fresh payload: { name, level, dataScope, menus } without id.
- Reset the role form whenever opening it in create mode.
Example fix
// before (clone a role)
axios.post('/api/roles', this.roleRow)
// after
const { id, ...payload } = this.roleRow;
axios.post('/api/roles', payload) Defensive patterns
Strategy: validation
Validate before calling
const { id, ...payload } = roleRow; // clone without identity
axios.post('/api/roles', payload); Type guard
const isCreateSafe = (r) => r.id == null;
Prevention
- Separate 'clone role' logic from raw entity POST.
- Reset role dialog state; include level explicitly so checkLevel does not hit the null branch.
When it happens
Trigger: Role dialog left populated after an edit and reused for create; POSTing a RoleDto from GET /api/roles to clone a role's permission set; importing roles from another deployment with ids intact.
Common situations: 'Copy role' workflows where the client posts the fetched role verbatim; shared add/edit dialog without form reset; environment sync scripts.
Related errors
- A new dept cannot already have an ID
- A new dict cannot already have an ID
- A new dictDetail cannot already have an ID
- A new job cannot already have an ID
- A new menu cannot already have an ID
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/7ee4fe7705c96467.
Report an issue: GitHub.