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

  1. Read the text after 'Unable to build target:' — it names the real exception and is the fastest route to the fix
  2. Validate option keys/values against GET /api/gen/clients/{language}/options (types, enums, defaults) before posting
  3. Reproduce locally with the openapi-generator CLI of the same version to iterate faster on the same inputs
  4. 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

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


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/aea5924c6763aa2c. Report an issue: GitHub.