{"record":{"id":"adcdc7d95e861e85","repo":"pinpoint-apm/pinpoint","slug":"node-key-must-not-be-null-or-empty","errorCode":null,"errorMessage":"Node key must not be null or empty","messagePattern":"Node key must not be null or empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"web/src/main/java/com/navercorp/pinpoint/web/applicationmap/controller/ServerMapHistogramController.java","lineNumber":265,"sourceCode":"\n\n    private Range toRange(RangeForm rangeForm) {\n        Range between = Range.between(rangeForm.getFrom(), rangeForm.getTo());\n        this.rangeValidator.validate(between);\n        return between;\n    }\n\n    private SearchOption.Builder searchOptionBuilder() {\n        return SearchOption.newBuilder(DEFAULT_MAX_SEARCH_DEPTH);\n    }\n\n    private Application getApplication(Service service, ApplicationForm appForm) {\n        return applicationValidator.newApplication(service, appForm.getApplicationName(), appForm.getServiceTypeCode(), appForm.getServiceTypeName());\n    }\n\n    private Application newApplication(Service service, String nodeKey) {\n        if (!StringUtils.hasLength(nodeKey)) {\n            throw new IllegalArgumentException(\"Node key must not be null or empty\");\n        }\n        if (!NODE_KEY_VALIDATION_PATTERN.matcher(nodeKey).matches()) {\n            throw new IllegalArgumentException(\"Invalid node key format: \" + nodeKey);\n        }\n        String[] parts = NODE_DELIMITER_PATTERN.split(nodeKey, 2);\n        String applicationName = parts[0];\n        String serviceTypeName = parts[1];\n\n        ServiceType serviceType = null;\n        if (StringUtils.hasLength(serviceTypeName)) {\n            serviceType = registry.findServiceTypeByName(serviceTypeName);\n        }\n        if (serviceType != null && serviceType.getCode() != ServiceType.UNDEFINED.getCode()) {\n            return new Application(service, applicationName, serviceType);\n        }\n        throw new IllegalArgumentException(\"Invalid or undefined service type for application: \" + nodeKey);\n    }\n","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/controller/ServerMapHistogramController.java#L247-L283","documentation":"ServerMapHistogramController.newApplication parses a 'nodeKey' string of the form '<applicationName><DELIMITER><serviceTypeName>' into an Application. If the key is null or empty (StringUtils.hasLength fails) it throws IllegalArgumentException before any parsing. It is invoked via nodeApplication/fromApplication/toApplication for every node referenced by a statistics query.","triggerScenarios":"Calling /serverMapHistogram/statistics endpoints with an empty or missing node key parameter (fromApplicationNames/toApplicationNames entries that are empty strings), so newApplication receives an empty nodeKey.","commonSituations":"Query strings like fromApplicationNames=,app1 built by joining arrays with empty members; UI state that lost the selected node; API clients omitting required parameters.","solutions":["Ensure every node key parameter value is non-empty in the form 'appName^serviceTypeName'","Strip empty strings from the lists before sending the request","Check the UI/client is actually setting the selected node key"],"exampleFix":"// before\n?fromApplicationNames=,app1&fromServiceTypeCodes=1010,1010\n// after (filter empties)\nString[] names = raw.split(\",\"); List<String> valid = stream.filter(s -> !s.isBlank()).toList();","handlingStrategy":"validation","validationCode":"boolean hasNodeKey(String key) {\n    return key != null && !key.isBlank();\n}\n// filter empty entries before building fromApplicationNames/toApplicationNames","typeGuard":"Optional<String> safeNodeKey(String key) {\n    return (key == null || key.isBlank()) ? Optional.empty() : Optional.of(key);\n}","tryCatchPattern":"try {\n    view = api.getNodeHistogramStatistics(nodeKey);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Node key must not be null or empty\")) {\n        // skip this node / surface input error\n    } else throw e;\n}","preventionTips":["Filter blank entries out of name/code arrays before joining into query strings","Check the UI actually holds a selected node before enabling the statistics call","Treat node key parameters as required and fail fast client-side"],"tags":["validation","illegal-argument","node-key"],"backgroundTag":"empty-required-field","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}