{"record":{"id":"edc475e9a2f5bafa","repo":"apache/seatunnel","slug":"log-file-path-is-empty-get-logref-s","errorCode":null,"errorMessage":"Log file path is empty, get logRef : %s","messagePattern":"Log file path is empty, get logRef : (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/utils/LogUtil.java","lineNumber":54,"sourceCode":"        String fileAppender = \"fileAppender\";\n        PropertiesConfiguration config = getLogConfiguration();\n        // Get routingAppender log file path\n        String routingLogFilePath = getRoutingLogFilePath(config);\n\n        // Get fileAppender log file path\n        String fileLogPath = getFileLogPath(config);\n        String logRef =\n                config.getLoggerConfig(StringUtils.EMPTY).getAppenderRefs().stream()\n                        .map(Object::toString)\n                        .filter(ref -> ref.contains(routingAppender) || ref.contains(fileAppender))\n                        .findFirst()\n                        .orElse(StringUtils.EMPTY);\n        if (logRef.equals(routingAppender)) {\n            return routingLogFilePath.substring(0, routingLogFilePath.lastIndexOf(\"/\"));\n        } else if (logRef.equals(fileAppender)) {\n            return fileLogPath.substring(0, fileLogPath.lastIndexOf(\"/\"));\n        } else {\n            throw new IllegalArgumentException(\n                    String.format(\"Log file path is empty, get logRef : %s\", logRef));\n        }\n    }\n\n    private static PropertiesConfiguration getLogConfiguration() {\n        LoggerContext context = (LoggerContext) LogManager.getContext(false);\n        return (PropertiesConfiguration) context.getConfiguration();\n    }\n\n    private static String getRoutingLogFilePath(PropertiesConfiguration config)\n            throws NoSuchFieldException, IllegalAccessException {\n        Field propertiesField = BuiltConfiguration.class.getDeclaredField(\"appendersComponent\");\n        propertiesField.setAccessible(true);\n        Component propertiesComponent = (Component) propertiesField.get(config);\n        StrSubstitutor substitutor = config.getStrSubstitutor();\n        return propertiesComponent.getComponents().stream()\n                .filter(\n                        component ->","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/utils/LogUtil.java#L36-L72","documentation":"Thrown by LogUtil.getLogPath when the resolved log reference matches neither the routing appender nor the file appender — usually because the required log path properties in log4j2 configuration resolved to empty strings. The method cannot determine the node's log directory and fails with the offending logRef in the message.","triggerScenarios":"Calling LogUtil.getLogPath(\"client\"|\"master\"|\"worker\") when the log4j2 config lacks the expected property (e.g. SEATUNNEL_HOME unset so ${sys:SEATUNNEL_HOME} expands empty) and no appender path matched.","commonSituations":"Running the client outside $SEATUNNEL_HOME so SEATUNNEL_HOME env/sys property is missing; a customized log4j2.client/log4j2.properties that renamed or removed the routing/file appenders; corrupted log config after manual edits.","solutions":["Ensure SEATUNNEL_HOME is set correctly and the process is started via bin/seatunnel.sh so sys properties are populated.","Restore the stock log4j2 configuration files (log4j2.client.properties / log4j2.properties) or re-add the routingAppender/fileAppender definitions that getLogPath expects.","Check that the appenders' fileName properties resolve to non-empty values (no blank placeholders in the config)."],"exampleFix":"# before (custom log4j2.properties)\nappender.file.fileName =\n# after\nappender.file.fileName = ${sys:SEATUNNEL_HOME}/logs/seatunnel-engine-server.log","handlingStrategy":"try-catch","validationCode":"String home = System.getenv(\"SEATUNNEL_HOME\");\nif (home == null || home.isEmpty()) throw new IllegalStateException(\"SEATUNNEL_HOME must be set before computing log path\");","typeGuard":null,"tryCatchPattern":"try { String path = LogUtil.getLogPath(\"worker\"); } catch (IllegalArgumentException e) { log.warn(\"log path unresolvable, check log4j2 config appenders\", e); }","preventionTips":["Always start nodes/clients via bin/seatunnel.sh so SEATUNNEL_HOME sys properties are injected.","Do not rename or delete routingAppender/fileAppender in log4j2 config customizations.","Keep log config files versioned and diff them after upgrades."],"tags":["logging","configuration","zeta-engine"],"backgroundTag":"missing-config-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}