{"record":{"id":"ebd31fbe567ec65a","repo":"pentaho/pentaho-kettle","slug":"a-server-socket-allocation-always-has-to-accompanied-by-a-ebd31f","errorCode":null,"errorMessage":"A server socket allocation always has to accompanied by a target step copy but it was empty","messagePattern":"A server socket allocation always has to accompanied by a target step copy but it was empty","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/TransformationMap.java","lineNumber":197,"sourceCode":"    }\n    if ( Utils.isEmpty( targetSlaveName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target slave server name but it was empty\" );\n    }\n    if ( Utils.isEmpty( sourceStepName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a source step name but it was empty\" );\n    }\n    if ( Utils.isEmpty( targetStepName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target step name but it was empty\" );\n    }\n    if ( Utils.isEmpty( sourceStepCopy ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a source step copy but it was empty\" );\n    }\n    if ( Utils.isEmpty( targetStepCopy ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target step copy but it was empty\" );\n    }\n\n      // Look up the sockets list for the given host\n      //\n    List<SocketPortAllocation> serverSocketPorts;\n    serverSocketPorts = hostServerSocketPortsMap.computeIfAbsent( hostname, k -> new CopyOnWriteArrayList<>() );\n    serverSocketPorts = serverSocketPorts != null ? serverSocketPorts : hostServerSocketPortsMap.get( hostname );\n\n        // Find the socket port allocation in the list...\n        //\n    SocketPortAllocation socketPortAllocation = null;\n    int maxPort = portRangeStart - 1;\n    for ( int index = 0; index < serverSocketPorts.size(); index++ ) {\n      SocketPortAllocation spa = serverSocketPorts.get( index );\n      if ( spa.getPort() > maxPort ) {\n        maxPort = spa.getPort();\n      }","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/TransformationMap.java#L179-L215","documentation":"Thrown by TransformationMap.allocateServerSocketPort when targetStepCopy is empty. Like the source copy, the target step's copy number is required to fully identify the server socket on the receiving slave. This is the last validation before the method proceeds to look up the host's socket port list.","triggerScenarios":"Calling allocateServerSocketPort with targetStepCopy=null or \"\"; missing copy generation for the clustered target step.","commonSituations":"Partitioned cluster steps without generated copy numbers; programmatic registration omitting copy arguments; transformations edited externally so copy metadata was lost.","solutions":["Generate the target step copy number (e.g. \"0\") before clustered registration","Pass the target step's copy string to allocateServerSocketPort","Validate with Utils.isEmpty( targetStepCopy ) before the call"],"exampleFix":"// before\nmap.allocateServerSocketPort( 40000, host, trans, src, tgt, \"stepA\", \"stepB\", \"0\", \"\" );\n// after\nmap.allocateServerSocketPort( 40000, host, trans, src, tgt, \"stepA\", \"stepB\", \"0\", targetCopyNr );","handlingStrategy":"validation","validationCode":"if ( Utils.isEmpty( targetStepCopy ) ) {\n  throw new IllegalArgumentException( \"target step copy number required\" );\n}","typeGuard":"boolean hasCopy(String s) { return s != null && s.matches( \"\\\\d+\" ); }","tryCatchPattern":"try {\n  map.allocateServerSocketPort( port, host, trans, src, tgt, stepA, stepB, srcCopy, tgtCopy );\n} catch ( RuntimeException e ) {\n  if ( e.getMessage().contains( \"target step copy\" ) ) {\n    // regenerate target step copy numbering\n  }\n}","preventionTips":["Verify all clustered step copies are numbered before execution","Validate SocketPortAllocation inputs in a helper before calling the API","Keep cluster generation code in one reviewed utility"],"tags":["java","kettle","carte","clustering"],"backgroundTag":"empty-required-field","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}