halo-dev/halo · warning · ServerWebInputException
Illegal requires version expression.
Error message
Illegal requires version expression.
What it means
Thrown as ServerWebInputException (HTTP 400) by VersionUtils.checkVersionConstraint when parsing/evaluating a SemVer constraint expression throws any exception. It wraps failures from com.github.zafarkhaja.semver (invalid version or malformed expression) into a client-facing bad-input error. Blank or '*' constraints are allowed and never reach the parser.
Source
Thrown at application/src/main/java/run/halo/app/infra/utils/VersionUtils.java:46
/**
* Checks if a version satisfies the specified SemVer {@link Expression} string. If the constraint is empty or null
* then the method returns true. Constraint examples: {@code >2.0.0} (simple), {@code ">=1.4.0 & <1.6.0"} (range).
* See <a
* href="https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges">semver-expressions-api-ranges</a> for
* more info.
*
* @param version the version to check
* @param constraint the SemVer Expression string
* @return true if version satisfies the constraint or if constraint was left blank
*/
public static boolean checkVersionConstraint(String version, String constraint) {
try {
return StringUtils.isBlank(constraint)
|| "*".equals(constraint)
|| Version.parse(version).satisfies(constraint);
} catch (Exception e) {
throw new ServerWebInputException("Illegal requires version expression.", null, e);
}
}
}
View on GitHub (pinned to d2f5165f9c)
Solutions
- Fix the constraint expression to valid SemVer syntax (e.g. '>=1.4.0 & <2.0.0', '~1.2', '^1.2.3').
- Leave the constraint blank or set it to '*' if any version is acceptable.
- Validate the expression with a SemVer parser locally before deploying the plugin.
- Confirm the version being matched is a clean x.y.z SemVer string.
Example fix
// before requires: ">>2.0.0" // after requires: ">=2.0.0"
Defensive patterns
Strategy: validation
Validate before calling
if (StringUtils.isNotBlank(constraint) && !"*".equals(constraint)) {
try {
Version.parse(version).satisfies(constraint);
} catch (Exception parseEx) {
throw new IllegalArgumentException("Invalid SemVer constraint: " + constraint, parseEx);
}
} Type guard
static boolean isValidSemverConstraint(String c) {
if (StringUtils.isBlank(c) || "*".equals(c)) return true;
try { Version.valueOf("1.0.0").satisfies(c); return true; } catch (Exception e) { return false; }
} Try / catch
try {
boolean ok = VersionUtils.checkVersionConstraint(version, requires);
} catch (ServerWebInputException e) {
// HTTP 400 already; surface to plugin author with the parse error
return ServerResponse.badRequest().bodyValue("Invalid 'requires' expression: " + e.getCause().getMessage());
} Prevention
- Lint plugin 'requires' with a SemVer parser during plugin build.
- Keep constraints to well-known operators (>=, <, ~, ^, ranges with &).
- Test the constraint against the target Halo version before release.
When it happens
Trigger: A plugin 'requires' / version-constraint string that is non-blank, not '*', and either is an unparseable version or a malformed SemVer expression (e.g. '>>2.0.0', 'foo', '1.x&<2').
Common situations: A plugin manifest with a typo in requires; an unsupported operator; copy-pasting npm-style ranges into a SemVer field; version strings with build metadata in an invalid position.
Related errors
- User permissions not set in PermissionUtils
- ESM provider manifest must be an object.
- ESM provider manifest must contain format, entry, and option
- Plugin name must not be blank
- Invalid attachment
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/8f78d2ad0cbfdd79.
Report an issue: GitHub.