OpenAPITools/openapi-generator · error · ResponseStatusException
Unable to build target: " + e.getMessage()
Error message
Unable to build target: " + e.getMessage()
What it means
The catch-all around DefaultGenerator().generate() and ZipUtil.compressFiles (Generator.java:174-176): any exception during template processing, option application, or zipping is rethrown as 400 'Unable to build target: <original message>'. This is the most common failure of the generate endpoints and intentionally leaks the underlying cause text, which is your only diagnostic. The underlying exception ranges from invalid option values to NPEs inside individual generator templates.
Source
Thrown at modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/Generator.java:175
zip.compressFiles(filesToAdd, outputFilename);
} else {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"A target generation was attempted, but no files were created!");
}
for (File file : files) {
try {
file.delete();
} catch (Exception e) {
LOGGER.error("unable to delete file " + file.getAbsolutePath(), e);
}
}
try {
new File(outputFolder).delete();
} catch (Exception e) {
LOGGER.error("unable to delete output folder " + outputFolder, e);
}
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Unable to build target: " + e.getMessage(), e);
}
return outputFilename;
}
private static File getTmpFolder() {
try {
File outputFolder = Files.createTempDirectory("codegen-tmp").toFile();
outputFolder.deleteOnExit();
return outputFolder;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Cannot access tmp folder");
}
}
}
View on GitHub (pinned to fcec517be3)
Solutions
- Read the text after 'Unable to build target:' — it names the real exception and is the fastest route to the fix
- Validate option keys/values against GET /api/gen/clients/{language}/options (types, enums, defaults) before posting
- Reproduce locally with the openapi-generator CLI of the same version to iterate faster on the same inputs
- For spec-semantic complaints (operationIds, naming), fix the spec; for template/NPE errors, try another generator or file an issue with the exact message
Example fix
# before: fire-and-forget POST, message lost
curl -s -X POST "$host/api/gen/clients/java" -H 'Content-Type: application/json' -d @req.json > /dev/null
# after: surface the embedded cause
resp=$(curl -s -w '\n%{http_code}' -X POST "$host/api/gen/clients/java" \
-H 'Content-Type: application/json' -d @req.json)
status=$(echo "$resp" | tail -1)
[ "$status" != 200 ] && { echo "$resp" | head -n -1; exit 1; } # prints Unable to build target: <cause> Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check option names and value types against the generator's own catalog
Map<String, CliOption> catalog = restTemplate.getForObject(
host + "/api/gen/clients/{l}/options", new ParameterizedTypeReference<>() {}, language);
for (Map.Entry<String, Object> kv : desiredOptions.entrySet()) {
CliOption o = catalog.get(kv.getKey());
if (o == null) throw new IllegalArgumentException("unknown option " + kv.getKey());
if (o.getEnum() != null && !o.getEnum().contains(String.valueOf(kv.getValue())))
throw new IllegalArgumentException(kv.getKey() + " must be one of " + o.getEnum());
} Try / catch
catch (HttpClientErrorException.BadRequest e) {
String body = e.getResponseBodyAsString();
if (body.contains("Unable to build target")) {
// the tail after the colon is the real generator exception — log it verbatim
log.error("generation failed: {}", body.substring(body.indexOf(':') + 1).trim());
}
} Prevention
- Always log the full response body — the embedded cause message is the diagnosis
- Validate options against GET .../options (names, types, enums) before posting
- Reproduce with the matching openapi-generator CLI locally to iterate on spec fixes
When it happens
Trigger: Invalid option values (e.g. non-numeric string for a numeric option, bad artifactId/packageName format); specs with semantic problems (duplicate operationIds, invalid names for the target language); generator-specific template exceptions; missing required option for a given generator; zipping failing because the tmp disk is full.
Common situations: Passing CLI-style options verbatim ('--artifactId=x' instead of {"artifactId":"x"}); specs that validate but break one specific generator; version skew between spec features and generator support; self-hosted servers with truncated classpaths throwing inside template code.
Related errors
- A target generation was attempted, but no files were created
- Framework is required
- No options were supplied
- No OpenAPI specification was supplied
- The OpenAPI specification supplied was not valid
AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22).
Data as JSON: /api/errors/aea5924c6763aa2c.
Report an issue: GitHub.