{"record":{"id":"82d442ed21844b31","repo":"apache/shenyu","slug":"parameter-error","errorCode":null,"errorMessage":"parameter error","messagePattern":"parameter error","errorType":"validation","errorClass":"ShenyuException","httpStatus":null,"severity":"error","filePath":"shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AiProxyApiKeyServiceImpl.java","lineNumber":88,"sourceCode":"            final AiProxyRealKeyResolver realKeyResolver) {\n        this.mapper = mapper;\n        this.eventPublisher = eventPublisher;\n        this.realKeyResolver = realKeyResolver;\n    }\n\n    @Override\n    @Transactional(rollbackFor = Exception.class)\n    public int create(final ProxyApiKeyDTO dto, final String selectorId) {\n        final ProxyApiKeyDO entity = ProxyApiKeyTransfer.INSTANCE.mapToEntity(dto);\n        if (StringUtils.isBlank(entity.getId())) {\n            entity.setId(UUIDUtils.getInstance().generateShortUuid());\n        }\n        if (StringUtils.isBlank(entity.getProxyApiKey())) {\n            entity.setProxyApiKey(SignUtils.generateKey());\n        }\n        // validate namespace\n        if (StringUtils.isBlank(entity.getNamespaceId())) {\n            throw new ShenyuException(ShenyuResultMessage.PARAMETER_ERROR);\n        }\n        // validate selector id\n        if (StringUtils.isBlank(selectorId)) {\n            throw new ShenyuException(ShenyuResultMessage.PARAMETER_ERROR);\n        }\n        entity.setSelectorId(selectorId);\n        // unique check for proxyApiKey if provided\n        if (StringUtils.isNotBlank(entity.getProxyApiKey())\n                && Boolean.TRUE.equals(mapper.proxyApiKeyExisted(selectorId, entity.getProxyApiKey()))) {\n            throw new ShenyuException(ShenyuResultMessage.UNIQUE_INDEX_CONFLICT_ERROR);\n        }\n        if (Objects.isNull(entity.getEnabled())) {\n            entity.setEnabled(Boolean.TRUE);\n        }\n        // back fill generated fields to response dto first\n        dto.setId(entity.getId());\n        dto.setProxyApiKey(entity.getProxyApiKey());\n        dto.setEnabled(entity.getEnabled());","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AiProxyApiKeyServiceImpl.java#L70-L106","documentation":"AiProxyApiKeyServiceImpl.create() validates the incoming ProxyApiKeyDTO before inserting an AI proxy API key record. When the DTO carries no namespaceId (namespace blank), ShenyuResultMessage.PARAMETER_ERROR is thrown as a ShenyuException, aborting the transaction. The namespace is mandatory because keys are scoped per namespace in ShenYu's multi-tenant model.","triggerScenarios":"POSTing/PUTing an AI proxy API key whose JSON body omits namespaceId (or sends it as null/empty string); a client DTO deserialized from a partial payload; a dashboard form that fails to include the namespace field. Reached via createOrUpdate when the record is new (no id).","commonSituations":"Dashboard or scripts calling /ai-proxy-key endpoints with hand-written payloads; API consumers upgrading to the multi-namespace version of ShenYu without updating payloads; copy-pasted curl commands missing namespaceId.","solutions":["Add a non-blank namespaceId to the request DTO before calling create/createOrUpdate.","In the dashboard/form, ensure the namespace selector value is bound and not empty on submit.","Server-side: pre-validate dto.getNamespaceId() and return a 400 with a clearer field-specific message instead of the generic PARAMETER_ERROR."],"exampleFix":"// before\n{\"proxyApiKey\":\"my-key\"}\n// after\n{\"proxyApiKey\":\"my-key\",\"namespaceId\":\"649330b6-1106-4a1f-8f9c-c292a62d2fda\"}","handlingStrategy":"validation","validationCode":"if (dto == null || dto.getNamespaceId() == null || dto.getNamespaceId().isBlank()) {\n    throw new IllegalArgumentException(\"namespaceId is required to create an AI proxy API key\");\n}\napiKeyService.createOrUpdate(dto, selectorId);","typeGuard":"boolean hasNamespace(ProxyApiKeyDTO dto) {\n    return dto != null && StringUtils.isNotBlank(dto.getNamespaceId());\n}","tryCatchPattern":"try {\n    apiKeyService.createOrUpdate(dto, selectorId);\n} catch (ShenyuException e) {\n    if (ShenyuResultMessage.PARAMETER_ERROR.equals(e.getMessage())) {\n        // 400: namespaceId missing in payload\n    }\n    throw e;\n}","preventionTips":["Always include namespaceId in AI proxy key payloads; fetch it from the authenticated session/tenant context.","Add client-side form validation requiring namespace selection before submit.","Add a bean-validation @NotBlank on the DTO's namespaceId for fail-fast error messages."],"tags":["validation","admin-api","missing-field"],"backgroundTag":"empty-required-field","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}