{"record":{"id":"8b2dcde7eeee5af1","repo":"dromara/Sa-Token","slug":"code-30024","errorCode":"CODE_30024","errorMessage":"缺少参数：{key}","messagePattern":"缺少参数：\\{key\\}","errorType":"exception","errorClass":"SaSsoException","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessage.java","lineNumber":121,"sourceCode":"    }\n\n    @Override\n    public SaSsoMessage delete(String key) {\n        super.remove(key);\n        return this;\n    }\n\n    // -----------\n\n    /**\n     * 获取一个值 （此值必须存在，否则抛出异常 ）\n     * @param key 键\n     * @return 参数值\n     */\n    public Object getValueNotNull(String key) {\n        Object value = get(key);\n        if(SaFoxUtil.isEmpty(value)) {\n            throw new SaSsoException(\"缺少参数：\" + key).setCode(SaSsoErrorCode.CODE_30024);\n        }\n        return value;\n    }\n\n}\n","sourceCodeStart":103,"sourceCodeEnd":127,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessage.java#L103-L127","documentation":"Thrown by SaSsoMessage.getValueNotNull(String key) when the requested key is absent or its value is empty. This is a strict-read accessor: the SSO protocol expects mandatory fields (loginId, ticket, client, etc.) to be present, and a missing one means the peer sent an incomplete or malformed message.","triggerScenarios":"Calling getValueNotNull(\"loginId\") / getValueNotNull(\"ticket\") on a SaSsoMessage whose map lacks that key, typically when processing a check-ticket or logout response from sso-server that did not include the expected parameter.","commonSituations":"The sso-server and sso-client run different sa-token versions with different parameter names (customized paramName); a proxy or gateway stripped query/body parameters; the server responded with a business failure payload instead of the expected data.","solutions":["Log the full message map (msg.getDataMap()) to see which keys actually arrived","Align paramName configuration (sa-token.sso.param-name.*) between sso-server and sso-client so both sides use the same key names","Upgrade client and server to the same sa-token version so the message contract matches"],"exampleFix":"// before\nObject loginId = message.getValueNotNull(\"loginId\"); // throws if server used a custom param name\n\n// after\n// align param names, or read defensively\nObject loginId = message.get(paramName.loginId);\nif(SaFoxUtil.isEmpty(loginId)) {\n    throw new SaSsoException(\"server response missing loginId\");\n}","handlingStrategy":"validation","validationCode":"Object v = message.get(key);\nif(SaFoxUtil.isEmpty(v)) {\n    // return 400 / log which key is missing instead of throwing deep in processing\n}","typeGuard":null,"tryCatchPattern":"try { message.getValueNotNull(key); } catch (SaSsoException e) { if(SaSsoErrorCode.CODE_30024 == e.getCode()) { /* log message map, reject */ } }","preventionTips":["Keep paramName configuration identical on both SSO sides","Log the full message payload when protocol errors occur so missing keys are obvious"],"tags":["sa-token","sso","validation","protocol"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}