{"record":{"id":"976b3ba678f704db","repo":"dromara/Sa-Token","slug":"code-30021","errorCode":"CODE_30021","errorMessage":"未能找到消息处理器: {type}","messagePattern":"未能找到消息处理器: (.+?)","errorType":"exception","errorClass":"SaSsoException","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java","lineNumber":104,"sourceCode":"     * 获取指定类型的消息处理器\n     *\n     * @param type /\n     */\n    public SaSsoMessageHandle getHandle(String type) {\n        return messageHandleMap.get(type);\n    }\n\n    /**\n     * 处理指定消息\n     *\n     * @param ssoTemplate /\n     * @param message /\n     * @return 处理结果\n     */\n    public Object handleMessage(SaSsoTemplate ssoTemplate, SaSsoMessage message) {\n        SaSsoMessageHandle handle = messageHandleMap.get(message.getType());\n        if(handle == null) {\n            throw new SaSsoException(\"未能找到消息处理器: \" + message.getType()).setCode(SaSsoErrorCode.CODE_30021);\n        }\n        return handle.handle(ssoTemplate, message);\n    }\n\n}\n","sourceCodeStart":86,"sourceCodeEnd":110,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java#L86-L110","documentation":"Thrown by SaSsoMessageHolder.handleMessage when no SaSsoMessageHandle is registered in messageHandleMap for message.getType(). The holder dispatches SSO messages by type string; an unregistered type means this node cannot process the message (e.g. a newer message type sent by a peer).","triggerScenarios":"sso-server pushes a message of a type this client never registered (e.g. a new message type introduced in a newer sa-token version), or a custom type string was set on the message but the corresponding handler was not added via the holder's registration API.","commonSituations":"Version mismatch between sso-server and sso-client (server newer than client); typo in the custom message type string; forgetting to register a custom SaSsoMessageHandle before receiving that message type.","solutions":["Register a handler for the type before it can arrive: messageHolder.putMessageHandle(\"the-type\", ssoTemplate -> ...)","Align sa-token versions on server and client so both know the same message types","Check for typos between setType(...) on the sender and the key used when registering the handler"],"exampleFix":"// before\nSaSsoMessage msg = new SaSsoMessage().setType(\"custom-notify\");\nclientTemplate.messageHolder.handleMessage(ssoTemplate, msg); // CODE_30021\n\n// after\nclientTemplate.messageHolder.putMessageHandle(\"custom-notify\", (ssoTemplate, message) -> {\n    // handle it\n    return SaResult.ok();\n});\nclientTemplate.messageHolder.handleMessage(ssoTemplate, msg);","handlingStrategy":"validation","validationCode":"if(ssoTemplate.messageHolder.getMessageHandle(message.getType()) == null) {\n    // unknown type: drop or register handler before dispatch\n}","typeGuard":null,"tryCatchPattern":"try { holder.handleMessage(tpl, msg); } catch (SaSsoException e) { if(SaSsoErrorCode.CODE_30021 == e.getCode()) { /* respond 'unsupported message type' */ } }","preventionTips":["Register all custom message handlers at application startup, not lazily","Pin server and client to the same sa-token version"],"tags":["sa-token","sso","dispatch","version-mismatch"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}