theonedev/onedev · error · ExplicitException
Invalid report name
Error message
Invalid report name
What it means
CoverageStats.checkReportName rejects any coverage report name containing ".." because the name is used to build file paths under a report directory; ".." would allow escaping that directory (path traversal). OneDev surfaces this as an ExplicitException with the message "Invalid report name".
Source
Thrown at server-core/src/main/java/io/onedev/server/codequality/CoverageStats.java:96
checkReportName(reportName);
Long projectId = build.getProject().getId();
Map<String, Map<Integer, CoverageStatus>> coveragesMap = OneDev.getInstance(ProjectService.class)
.runOnActiveServer(projectId, new GetLineCoverages(projectId, build.getNumber(),
blobPath, reportName));
Map<Integer, CoverageStatus> coverages = new HashMap<>();
for (var entry: coveragesMap.entrySet()) {
if (SecurityUtils.canAccessReport(build, entry.getKey())) {
entry.getValue().forEach((key, value) -> {
coverages.merge(key, value, CoverageStatus::mergeWith);
});
}
}
return coverages;
}
private static void checkReportName(String reportName) {
if (reportName.contains(".."))
throw new ExplicitException("Invalid report name");
}
public void writeTo(File reportDir) {
File reportFile = new File(reportDir, REPORT);
try (var os = new BufferedOutputStream(new FileOutputStream(reportFile), BUFFER_SIZE)) {
SerializationUtils.serialize(this, os);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getReportLockName(Build build) {
return getReportLockName(build.getProject().getId(), build.getNumber());
}
public static String getReportLockName(Long projectId, Long buildNumber) {
return CoverageStats.class.getName() + ":" + projectId + ":" + buildNumber;
}View on GitHub (pinned to d44925c47c)
Solutions
- Remove any ".." from the report name before calling the API
- Use a plain report name (single path segment, no traversal) and resolve parent directories outside the report name
- Sanitize/validate external input at the job or plugin boundary before passing it as a report name
Example fix
// before
var coverages = coverage.getLineCoverages("../other-project/report");
// after
String reportName = "unit-tests"; // no path separators or ".."
var coverages = coverage.getLineCoverages(reportName); Defensive patterns
Strategy: validation
Validate before calling
// validate before calling CoverageStats APIs
if (reportName == null || reportName.contains(".."))
throw new IllegalArgumentException("report name must not contain '..'");
if (reportName.contains("/") || reportName.contains("\\"))
throw new IllegalArgumentException("report name must be a single path segment"); Type guard
function isValidReportName(name) { return typeof name === 'string' && name.length > 0 && !name.includes('..') && !/[/\\]/.test(name); } Try / catch
try {
coverages = CoverageStats.readFrom(reportDir, reportName);
} catch (ExplicitException e) {
if ("Invalid report name".equals(e.getMessage())) {
reportName = sanitizeReportName(reportName); // strip '..' and separators
coverages = CoverageStats.readFrom(reportDir, reportName);
} else throw e;
} Prevention
- Treat report names from CI configs as untrusted input and sanitize them
- Use fixed, well-known report name constants where possible
- Add a pre-submit validator that rejects names containing '..'
- Never build report paths by concatenating user input
When it happens
Trigger: Calling CoverageStats.getLineCoverages(reportName) or readFrom(reportDir, reportName) with a reportName containing "..", e.g. "../secrets" or "a..b" patterns used as directory components.
Common situations: Untrusted report names piped from CI config, job step parameters, or REST payloads into the code quality report APIs; malicious or buggy build scripts passing relative paths as report names.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/8c6e455d5a10291c.
Report an issue: GitHub.