elastic/elasticsearch · error · GradleException
Cannot generate source from String template
Error message
Cannot generate source from String template
What it means
Thrown by StringTemplateTask.generate when an IOException occurs while rendering a StringTemplate (ST) template and writing the generated file. The task reads the input template, injects properties via st.add, renders with st.render(), normalizes CRLF to LF, creates parent directories, and writes the output; any I/O failure in that sequence is wrapped in this GradleException. Note ST's own template-syntax errors throw STException (a RuntimeException), not IOException — this catch specifically covers filesystem/encoding I/O.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/StringTemplateTask.java:93
ST st = new ST(Files.readString(spec.inputFile.toPath(), UTF_8), '$', '$');
for (var entry : spec.properties.entrySet()) {
if (entry.getValue().isEmpty()) {
st.add(entry.getKey(), null);
} else {
st.add(entry.getKey(), entry.getValue());
}
}
// ST's default AutoIndentWriter renders newlines using the platform's
// line.separator, so on Windows the output is CRLF regardless of the
// input template's own (LF) line endings. Normalize to LF explicitly so
// generated sources are consistent across OSes and match what spotless
// (configured with LineEnding.UNIX) expects.
String output = st.render().replace("\r\n", "\n");
Files.createDirectories(outputRootFolder.toPath().resolve(spec.outputFile).getParent());
Files.writeString(new File(outputRootFolder, spec.outputFile).toPath(), output, UTF_8);
getLogger().info("StringTemplateTask generated {}", spec.outputFile);
} catch (IOException e) {
throw new GradleException("Cannot generate source from String template", e);
}
}
}
class TemplateSpec {
private File inputFile;
private String outputFile;
private Map<String, String> properties;
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public File getInputFile() {
return inputFile;
}
public void setInputFile(File inputFile) {View on GitHub (pinned to db6a809a66)
Solutions
- Verify spec.inputFile exists and is readable (check the task's input file configuration and the logged 'StringTemplateTask generating {}' line just before the failure).
- Ensure getOutputFolder() resolves to a writable directory and that no regular file occupies a needed parent path.
- Check filesystem permissions and free space on the output volume.
- If running on Windows and the file is locked, close the holder (IDE/antivirus) or rerun.
- Distinguish from ST syntax errors: a template-parse failure surfaces as org.stringtemplate.v4.STException, not this message — fix the template delimiters ($...$) if that is the actual cause.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight before the task runs:
import java.nio.file.*;
Path in = spec.inputFile.toPath();
if (!Files.isReadable(in)) throw new IllegalArgumentException("unreadable template: " + in);
Path outDir = outputFolder.getAsFile().get().toPath();
Path outParent = outDir.resolve(spec.outputFile).getParent();
if (Files.exists(outParent) && !Files.isDirectory(outParent))
throw new IllegalArgumentException("output parent is not a directory: " + outParent);
if (!Files.isWritable(outParent))
throw new IllegalArgumentException("output dir not writable: " + outParent); Try / catch
try {
st.add(...); st.render(); Files.writeString(...);
} catch (java.io.IOException e) {
throw new GradleException("Cannot generate source from String template for "
+ spec.inputFile + " -> " + spec.outputFile, e);
} Prevention
- Validate the input template path exists and is readable before the task runs.
- Ensure getOutputFolder() is a writable directory and no regular file occupies a parent slot.
- Distinguish IOException (filesystem) from STException (template syntax); fix $...$ delimiters for the latter.
When it happens
Trigger: Inside the per-template try block: Files.readString(spec.inputFile.toPath()) fails (input missing/unreadable), st.render() is fine but Files.createDirectories(...) fails (permission/disk), or Files.writeString(...) fails (output path unwritable, parent is a file not a directory). The catch is narrow: catch (IOException e).
Common situations: The configured inputFile does not exist or is not readable; the outputFolder points to a read-only location or a path whose parent is a regular file; disk full or permissions denied during write; the output directory was deleted out from under the task; the input file is locked by another process on Windows.
Related errors
- Unable to create reaper JAR output directory {}
- Cannot create directory '%s' as it already exists, but is no
- Cannot create parent directory '%s' when creating directory
- Failed to create parent directory '%s' when creating directo
- Failed to create directory '%s'
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/a2685a4e639e0473.
Report an issue: GitHub.