google/tsunami-security-scanner · error · IllegalArgumentException

String ' ' is neither a discrete string nor a version range.

Error message

String '%s' is neither a discrete string nor a version range.

What it means

VersionSet.parse accepts a list of strings that must each be either a discrete version (parsed via Version.fromString) or a valid version range (parsed via VersionRange.parse). A string that fails both checks is rejected with this IllegalArgumentException.

Solutions

  1. Fix the offending string to be a valid version like "1.2.3" or a valid range like "[1.0,2.0)".
  2. Pre-validate each element with Version.fromString (in try/catch) and VersionRange.isValidVersionRange before calling parse.
  3. Check the log/output for the exact string quoted in the message and correct it in the config.

Example fix

// before
VersionSet.parse(Arrays.asList("1.0.0", "1.0;2.0"));
// after
VersionSet.parse(Arrays.asList("1.0.0", "[1.0,2.0]"));
Defensive patterns

Strategy: validation

Validate before calling

boolean ok(String s) { try { Version.fromString(s); return true; } catch (IllegalArgumentException e) { return VersionRange.isValidVersionRange(s); } }

Try / catch

try { VersionSet.parse(list); } catch (IllegalArgumentException e) { log.error("Bad version element: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling VersionSet.parse with any element that is neither a parseable version nor a string passing VersionRange.isValidVersionRange, e.g. "abc", "1.0;2.0", or a malformed range like "[1.0,".

Common situations: Typos in vulnerability-configuration version lists, semicolon- or space-separated versions pasted from other tools, or versions with invalid characters that fail Version.fromString.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of google/tsunami-security-scanner@363ba87b35 (2026-09-13). Data as JSON: /api/errors/0635bac3fb95fd7f. Report an issue: GitHub.

Appendix: source

Thrown at common/src/main/java/com/google/tsunami/common/version/VersionSet.java:67

      return this;
    }

    public abstract VersionSet build();
  }

  public static VersionSet parse(ImmutableList<String> versionAndRangesList) {
    checkNotNull(versionAndRangesList);
    checkArgument(!versionAndRangesList.isEmpty(), "Versions and ranges list cannot be empty.");

    VersionSet.Builder versionSetBuilder = VersionSet.builder();

    for (String versionOrRangeString : versionAndRangesList) {
      if (isDiscreteVersion(versionOrRangeString)) {
        versionSetBuilder.addVersion(Version.fromString(versionOrRangeString));
      } else if (VersionRange.isValidVersionRange(versionOrRangeString)) {
        versionSetBuilder.addVersionRange(VersionRange.parse(versionOrRangeString));
      } else {
        throw new IllegalArgumentException(
            String.format(
                "String '%s' is neither a discrete string nor a version range.",
                versionOrRangeString));
      }
    }

    return versionSetBuilder.build();
  }

  private static boolean isDiscreteVersion(String versionOrRangeString) {
    return CharMatcher.anyOf("[()], ").matchesNoneOf(versionOrRangeString);
  }
}

View on GitHub (pinned to 363ba87b35)