iflytek/astron-agent · warning · BusinessException
INVITE_PARAMETER_EXCEPTION
INVITE_PARAMETER_EXCEPTION
Error message
INVITE_PARAMETER_EXCEPTION
What it means
INVITE_PARAMETER_EXCEPTION is thrown by InviteRecordBizServiceImpl.getRecordByParam when the encrypted invitation 'param' cannot be decrypted with AES_KEY or the decrypted plaintext cannot be parsed as a Long id. It means the invitation link parameter is invalid, corrupted, or was encrypted with a different key. The service deliberately collapses all decrypt/parse failures into this single business error.
Solutions
- URL-encode the encrypted param when building invitation links and URL-decode it at the entry point so '+' and '/' survive transport
- Verify AES_KEY is identical across all nodes/environments generating and consuming invitation links
- Validate the param on the client before calling (non-empty, expected charset/length) and show 'invalid invitation link' instead of hitting the API
- Regenerate the invitation link if it predates a key rotation; old links cannot be recovered
Example fix
// before
String decrypt = AESUtil.decrypt(param, AES_KEY);
assert decrypt != null;
id = Long.parseLong(decrypt);
// after
String decrypt = AESUtil.decrypt(URLDecoder.decode(param, StandardCharsets.UTF_8), AES_KEY);
if (decrypt == null || !decrypt.chars().allMatch(Character::isDigit)) {
throw new BusinessException(ResponseEnum.INVITE_PARAMETER_EXCEPTION);
}
id = Long.parseLong(decrypt); Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check before calling the API
function canCallGetRecord(param) {
return typeof param === 'string' && param.length > 0 && /^[A-Za-z0-9+/=_-]+$/.test(param);
} Try / catch
// server-side callers
try {
InviteRecordVO vo = inviteRecordBizService.getRecordByParam(param);
} catch (BusinessException e) {
if (ResponseEnum.INVITE_PARAMETER_EXCEPTION.getCode().equals(e.getCode())) {
throw new BusinessException(ResponseEnum.INVITE_PARAMETER_EXCEPTION); // render 'invalid invitation link'
}
throw e;
} Prevention
- Always URL-encode the encrypted param in links and decode on receipt
- Keep AES_KEY synchronized across environments and document rotations (old links die)
- Never build invitation params by hand; use the shared encrypt utility
- Validate param shape client-side before the API call
When it happens
Trigger: Calling getRecordByParam with a param that is null, truncated (e.g. URL-decoding stripped characters like '+' becoming space), tampered with, or encrypted with a different AES key than AES_KEY; or a param whose decryption does not yield a numeric Long.
Common situations: Invitation links opened after the server's AES_KEY was rotated or differs across environments (staging link hit against prod); email/IM clients mangling the base64 ciphertext (line wraps, '+' to space in query strings); users truncating the link when copying; forwarding links between environments.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- INVITE_RECORD_NOT_FOUND
- INVITE_SPACE_ALREADY_DELETED
- User UID cannot be null
- Timed out acquiring distributed lock, please try again later
- Current user does not exist
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/aded012f35101a60.
Report an issue: GitHub.
Appendix: source
Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/space/impl/InviteRecordBizServiceImpl.java:403
}
/**
* Get invitation record by parameter
*
* @param param Invitation record ID AES encrypted
* @return
*/
@Override
public InviteRecordVO getRecordByParam(String param) {
long id = 0;
try {
String decrypt = AESUtil.decrypt(param, AES_KEY);
assert decrypt != null;
id = Long.parseLong(decrypt);
} catch (Exception e) {
log.error("Failed to parse invitation parameters", e);
throw new BusinessException(ResponseEnum.INVITE_PARAMETER_EXCEPTION);
}
InviteRecordVO vo = inviteRecordService.selectVOById(id);
if (vo == null) {
throw new BusinessException(ResponseEnum.INVITE_RECORD_NOT_FOUND);
}
UserInfo inviterUser = userInfoDataService.findByUid(vo.getInviterUid()).orElseThrow();
vo.setInviterName(inviterUser.getNickname());
vo.setInviterAvatar(inviterUser.getAvatar());
if (Objects.equals(InviteRecordTypeEnum.SPACE.getCode(), vo.getType())) {
SpaceUser spaceOwner = spaceUserService.getSpaceOwner(vo.getSpaceId());
if (spaceOwner != null) {
UserInfo ownerUser = userInfoDataService.findByUid(spaceOwner.getUid()).orElseThrow();
vo.setOwnerName(ownerUser.getNickname());
vo.setOwnerAvatar(ownerUser.getAvatar());
}
Space space = spaceService.getSpaceById(vo.getSpaceId());
if (space != null) {
vo.setSpaceName(space.getName());View on GitHub (pinned to 5e758547a8)