iflytek/astron-agent · warning · BusinessException
TOOLBOX_ALREADY_COLLECT
TOOLBOX_ALREADY_COLLECT
Error message
BusinessException(ResponseEnum.TOOLBOX_ALREADY_COLLECT)
What it means
The favorite/unfavorite flow throws TOOLBOX_ALREADY_COLLECT when favoriteFlag == 0 (favorite action) but userFavoriteToolMapper.findByUserIdAndToolId already returns a matching UserFavoriteTool row. Favoriting is idempotency-guarded: adding a duplicate favorite for the same tool (or MCP tool) is rejected rather than inserted twice.
Solutions
- Check the user's favorite list before calling favorite; skip if the tool is already present.
- Treat this error as success if the end state (favorited) is what the user wanted.
- Fix the UI to disable the favorite button (or flip to unfavorite) immediately after a successful favorite.
- If state is inconsistent, call unfavorite first (favoriteFlag=1) then favorite again.
Example fix
// before
userFavoriteToolMapper.findByUserIdAndToolId(userId, toolId)
.ifPresentOrElse(f -> {}, f -> favoriteService.add(userId, toolId));
// after
if (userFavoriteToolMapper.findByUserIdAndToolId(userId, toolId).isEmpty()) {
favoriteService.add(userId, toolId); // only favorite when absent
} Defensive patterns
Strategy: validation
Validate before calling
boolean alreadyFavorited = userFavoriteToolMapper.findByUserIdAndToolId(userId, toolId).isPresent();
if (!alreadyFavorited) { /* safe to send favoriteFlag=0 */ } Try / catch
try {
favoriteService.setFavorite(userId, toolId, 0);
} catch (BusinessException e) {
if ("TOOLBOX_ALREADY_COLLECT".equals(e.getCode())) {
// already favorited; sync UI state to favorited
}
} Prevention
- Sync the favorite toggle state from the server before rendering it.
- Debounce/disable the favorite button while a request is in flight.
- Treat duplicate favorite errors as success to keep UI and server consistent.
When it happens
Trigger: Calling the favorite API (favoriteFlag=0) for a tool the user already favorited; double-clicking the favorite button causing a second request; replaying a favorite request in a retry after the first one succeeded.
Common situations: Frontend favorite toggle out of sync with server state (optimistic UI not reverted); automated scripts that favorite tools without checking existing favorites; concurrent favorite calls from multiple tabs.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/0e17574f6b8bc11b.
Report an issue: GitHub.
Appendix: source
Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/tool/ToolBoxService.java:1240
* @return
*/
public Integer favorite(String toolId, Integer favoriteFlag, Boolean isMcp) {
AtomicReference<Integer> result = new AtomicReference<>();
result.set(0);
String userId = UserInfoManagerHandler.getUserId();
String redisKey = FAVORITE_KEY_PREFIX + userId;
Optional<UserFavoriteTool> existingFavorite;
if (isMcp) {
existingFavorite = userFavoriteToolMapper.findByUserIdAndMcpToolId(userId, toolId);
} else {
existingFavorite = userFavoriteToolMapper.findByUserIdAndToolId(userId, toolId);
}
// 0-favorite, 1-unfavorite
if (favoriteFlag == 0) {
// Already favorited
if (existingFavorite.isPresent()) {
throw new BusinessException(ResponseEnum.TOOLBOX_ALREADY_COLLECT);
}
UserFavoriteTool userFavorite = new UserFavoriteTool();
userFavorite.setUserId(userId);
userFavorite.setToolId(0L);
if (isMcp) {
userFavorite.setMcpToolId(toolId);
} else {
userFavorite.setPluginToolId(toolId);
}
userFavorite.setCreatedTime(new Timestamp(System.currentTimeMillis()));
// 1-indicates favorite
userFavorite.setUseFlag(1);
userFavoriteToolMapper.save(userFavorite);
redisTemplate.opsForSet().add(redisKey, toolId);
} else if (favoriteFlag == 1) {
if (existingFavorite.isPresent()) {
UserFavoriteTool userFavorite = existingFavorite.get();
userFavorite.setDeleted(true);View on GitHub (pinned to 5e758547a8)