{"record":{"id":"9ff2f1f7b9a264f4","repo":"kestra-io/kestra","slug":"invalid-outputfile-only-relative-path-is-supporte","errorCode":null,"errorMessage":"Invalid outputFile (only relative path is supported) for path '{}'","messagePattern":"Invalid outputFile \\(only relative path is supported\\) for path '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/models/tasks/runners/PluginUtilsService.java","lineNumber":79,"sourceCode":"                        String prefix = StringUtils.leftPad(s + \"_\", 3, \"_\");\n                        tempFile = File.createTempFile(prefix, null, tempDirectory.toFile());\n                    }\n\n                    result.put(s, additionalVars.get(\"workingDir\") + \"/\" + tempFile.getName());\n                }));\n\n            if (!isDir) {\n                additionalVars.put(\"temp\", result);\n            }\n            additionalVars.put(isDir ? \"outputDirs\" : \"outputFiles\", result);\n        }\n\n        return result;\n    }\n\n    private static void validFilename(String s) {\n        if (s.startsWith(\"./\") || s.startsWith(\"..\") || s.startsWith(\"/\")) {\n            throw new IllegalArgumentException(\n                \"Invalid outputFile (only relative path is supported) \" +\n                    \"for path '\" + s + \"'\"\n            );\n        }\n    }\n\n    public static Map<String, String> transformInputFiles(RunContext runContext, @NotNull Object inputFiles) throws IllegalVariableEvaluationException, JsonProcessingException {\n        return PluginUtilsService.transformInputFiles(runContext, Collections.emptyMap(), inputFiles);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static Map<String, String> transformInputFiles(RunContext runContext, Map<String, Object> additionalVars, @NotNull Object inputFiles)\n        throws IllegalVariableEvaluationException, JsonProcessingException {\n        if (inputFiles instanceof Map) {\n            Map<String, String> castedInputFiles = (Map<String, String>) inputFiles;\n            Map<String, String> nullFilteredInputFiles = new HashMap<>();\n            castedInputFiles.forEach((key, val) ->\n            {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/models/tasks/runners/PluginUtilsService.java#L61-L97","documentation":"Thrown by PluginUtilsService.validFilename() when an output file path starts with './', '..', or '/'. Only strictly relative paths (no leading traversal or absolute-root markers) are permitted, because output files are resolved relative to the task's working directory and an absolute or parent-relative path would escape the sandbox. This is an IllegalArgumentException surfaced during output-file rendering.","triggerScenarios":"A task declares outputFiles with an entry like '/out/data.csv', './out.txt', or '../escape.csv'; a Pebble expression renders to a path with a leading slash; the user sets an absolute path expecting it to be honored.","commonSituations":"User copies a local absolute path into the flow; template renders an unintended leading './'; confusion between outputFiles (relative) and external paths.","solutions":["Use a bare relative path with no leading './', '..', or '/' (e.g., 'out/data.csv').","If a subdirectory is needed, write 'subdir/file.txt' without a leading slash.","Audit Pebble templates that generate filenames to ensure no leading slash is produced."],"exampleFix":"# before\noutputFiles:\n  /out/data.csv\n\n# after\noutputFiles:\n  out/data.csv","handlingStrategy":"validation","validationCode":"static void ensureRelative(String s) {\n    if (s.startsWith(\"./\") || s.startsWith(\"..\") || s.startsWith(\"/\")) {\n        throw new IllegalArgumentException(\"Only relative paths are allowed: \" + s);\n    }\n}","typeGuard":"function isSafeRelativePath(p: string): boolean {\n  return !p.startsWith('./') && !p.startsWith('..') && !p.startsWith('/');\n}","tryCatchPattern":"try {\n    PluginUtilsService.transformOutputFiles(...);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Reject output path: {}\", e.getMessage());\n}","preventionTips":["Normalize user-supplied paths to relative form before assignment.","Strip leading './' and '/' from templated filenames."],"tags":["task-runner","validation","path","sandbox","output-files"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}