nathanmarz/storm · error · RuntimeException
is not a valid version
Error message
${path} is not a valid version What it means
VersionedStore.validateAndGetVersion parses a version number out of a version directory path. If the file name does not end with the finished-version suffix (or otherwise yields no parsable Long), it throws RuntimeException stating the path is not a valid version.
Solutions
- Pass only paths returned by createVersion / version() — never arbitrary files in the store root.
- Remove non-version files/directories from the store root directory.
- Inspect the directory: only names matching '<number>.finished' (finished suffix) are valid versions; rename or delete malformed leftovers from crashed writes.
- Catch RuntimeException around getAllVersions()/failVersion when the store dir may be dirty, and skip invalid entries.
Example fix
// before
store.failVersion(someDirPath); // someDirPath lacks the finished suffix
// after
if (new File(path).getName().endsWith(FINISHED_VERSION_SUFFIX_PATTERN)) {
store.failVersion(path);
} else {
LOG.warn("Ignoring non-version path: " + path);
} Defensive patterns
Strategy: validation
Validate before calling
String name = new File(path).getName();
if (!name.matches("\\d+" + FINISHED_VERSION_SUFFIX)) {
throw new IllegalArgumentException("Not a version dir: " + path);
} Type guard
boolean isValidVersionPath(String path) {
String name = new File(path).getName();
return name.endsWith(".finished") && name.replace(".finished", "").matches("\\d+");
} Try / catch
try {
long v = store.version(path);
} catch (RuntimeException e) {
LOG.warn("Skipping invalid version path " + path);
} Prevention
- Keep unrelated files out of the versioned store root
- Only pass paths produced by createVersion()/version() to failVersion
- Periodically clean temp/aborted dirs left by crashed writers
When it happens
Trigger: Calling failVersion(path), version(path), or getAllVersions() over a directory containing files/dirs under _root that are not version directories (e.g. temp dirs, checkpoint metadata, human-created files), so parseVersion returns null.
Common situations: Users placed unrelated files in the versioned store root; an interrupted createVersion left a non-conforming temp directory; a path built manually without the FINISHED_VERSION_SUFFIX was passed to failVersion.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Version already exists or data already exists
- Could not find component with id
- Don't know how to convert
- Each element of the list
- Field must be an Iterable of
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/7d42d5fe3a49038e.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/utils/VersionedStore.java:152
public List<Long> getAllVersions() throws IOException {
List<Long> ret = new ArrayList<Long>();
for(String s: listDir(_root)) {
if(s.endsWith(FINISHED_VERSION_SUFFIX)) {
ret.add(validateAndGetVersion(s));
}
}
Collections.sort(ret);
Collections.reverse(ret);
return ret;
}
private String tokenPath(long version) {
return new File(_root, "" + version + FINISHED_VERSION_SUFFIX).getAbsolutePath();
}
private long validateAndGetVersion(String path) {
Long v = parseVersion(path);
if(v==null) throw new RuntimeException(path + " is not a valid version");
return v;
}
private Long parseVersion(String path) {
String name = new File(path).getName();
if(name.endsWith(FINISHED_VERSION_SUFFIX)) {
name = name.substring(0, name.length()-FINISHED_VERSION_SUFFIX.length());
}
try {
return Long.parseLong(name);
} catch(NumberFormatException e) {
return null;
}
}
private void createNewFile(String path) throws IOException {
new File(path).createNewFile();
}View on GitHub (pinned to cdb116e942)