{"record":{"id":"3303cafbc0eff62b","repo":"pentaho/pentaho-kettle","slug":"there-was-an-error-during-transformation-split","errorCode":null,"errorMessage":"There was an error during transformation split","messagePattern":"There was an error during transformation split","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/Trans.java","lineNumber":3960,"sourceCode":"          // WG: Should these be threaded like the above initialization?\n          for ( int i = 0; i < slaves.length; i++ ) {\n            TransMeta slaveTrans = transSplitter.getSlaveTransMap().get( slaves[ i ] );\n            String carteObjectId = carteObjectMap.get( slaveTrans );\n            String slaveReply =\n              slaves[ i ].execService( StartExecutionTransServlet.CONTEXT_PATH + \"/?name=\" + URLEncoder.encode(\n                slaveTrans.getName(), \"UTF-8\" ) + \"&id=\" + URLEncoder.encode( carteObjectId, \"UTF-8\" ) + \"&xml=Y\" );\n            WebResult webResult = WebResult.fromXMLString( slaveReply );\n            if ( !webResult.getResult().equalsIgnoreCase( WebResult.STRING_OK ) ) {\n              throw new KettleException( \"An error occurred while starting the execution of a slave transformation: \"\n                + webResult.getMessage() );\n            }\n          }\n        }\n      }\n    } catch ( KettleException ke ) {\n      throw ke;\n    } catch ( Exception e ) {\n      throw new KettleException( \"There was an error during transformation split\", e );\n    }\n  }\n\n  /**\n   * Monitors a clustered transformation every second, after all the transformations in a cluster schema are running.\n   * <br>\n   * Now we should verify that they are all running as they should.<br>\n   * If a transformation has an error, we should kill them all.<br>\n   * This should happen in a separate thread to prevent blocking of the UI.<br>\n   * <br>\n   * When the master and slave transformations have all finished, we should also run<br>\n   * a cleanup on those transformations to release sockets, etc.<br>\n   * <br>\n   *\n   * @param log           the log interface channel\n   * @param transSplitter the transformation splitter object\n   * @param parentJob     the parent job when executed in a job, otherwise just set to null\n   * @return the number of errors encountered","sourceCodeStart":3942,"sourceCodeEnd":3978,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/Trans.java#L3942-L3978","documentation":"Catch-all wrapper in Trans.prepareExecution(String[]) for the clustered transformation split/prepare/start flow: any non-KettleException thrown while splitting the transformation across the cluster or talking to slaves is rethrown as this KettleException with the original as cause.","triggerScenarios":"Any unexpected Exception during Trans.splitOriginalTransformation or the prepare/start servlet loop on a clustered transformation: URLEncoder failure, XML parse of a slave reply, NPE from a null slave/carte object id, or IO problem inside execService surfaced as a generic exception.","commonSituations":"Malformed/non-XML response from a slave (proxy error page, HTML login page); null slave server in cluster schema; serialization failure of TransMeta during split; DNS resolution problems surfacing as raw IOException.","solutions":["Inspect the cause (getCause()) of this exception; the real problem is the wrapped exception.","Verify every slave server in the cluster schema is defined, non-null, and resolvable by hostname.","Check that slave responses are genuine Carte XML WebResults and not intercepted by a proxy or auth page.","Test the cluster schema with a trivial transformation to isolate split-specific issues.","Ensure the transformation itself serializes cleanly (valid step metadata, no broken plugin steps)."],"exampleFix":"// before: slave hostname typo causes generic split error\nslaveServer.setHostname(\"slvae1\");\n// after\nclass.ClusterSchema cs = transMeta.findClusterSchema(\"my-cluster\");\nfor (SlaveServer s : cs.getSlaveServers()) {\n  InetAddress.getByName(s.getHostname()); // fails fast with a clear cause\n}","handlingStrategy":"try-catch","validationCode":"// fail fast on unresolved hostnames and null slaves before splitting\nfor (SlaveServer s : transMeta.findClusterSchema(name).getSlaveServers()) {\n  Objects.requireNonNull(s, \"null slave server in schema\");\n  InetAddress.getByName(s.getHostname());\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.prepareExecution(new String[0]);\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"error during transformation split\")) {\n    Throwable root = e;\n    while (root.getCause() != null) root = root.getCause();\n    log.error(\"Split root cause: \" + root, root);\n  } else throw e;\n}","preventionTips":["Unwrap and log getCause() chain to find the real failure.","Validate every slave server entry (host, port, credentials) before running.","Ensure no proxy intercepts Carte HTTP responses with HTML.","Prove the transformation serializes cleanly by round-tripping TransMeta XML locally."],"tags":["kettle","clustered-transformation","split","unexpected-exception"],"backgroundTag":"api-request-failed","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"}