halo-dev/halo · error · UnsatisfiedAttributeValueException
problemDetail.theme.version.unsatisfied.requires
problemDetail.theme.version.unsatisfied.requires
Error message
The theme requires a minimum system version of %s, but the current version is %s.
What it means
During theme persistence (install or upgrade), ThemeServiceImpl.persistent() reads theme.spec.requires and checks it against the running system version via VersionUtils.satisfiesRequires(systemVersion, requires). If the semver requirement is not satisfied, an UnsatisfiedAttributeValueException is thrown with code 'problemDetail.theme.version.unsatisfied.requires' and the requires/systemVersion as arguments. This is a hard gate after the Theme CR is created/updated.
Source
Thrown at application/src/main/java/run/halo/app/theme/service/ThemeServiceImpl.java:209
*/
private Mono<Theme> persistent(Unstructured themeManifest, boolean isUpgrade) {
Assert.state(StringUtils.equals(Theme.KIND, themeManifest.getKind()), "Theme manifest kind must be Theme.");
var newTheme = Unstructured.OBJECT_MAPPER.convertValue(themeManifest, Theme.class);
final Mono<Theme> createOrUpdateTheme;
if (isUpgrade) {
createOrUpdateTheme = client.get(Theme.class, newTheme.getMetadata().getName())
.doOnNext(theme -> updateTheme(theme, newTheme))
.flatMap(client::update);
} else {
createOrUpdateTheme = client.create(newTheme);
}
return createOrUpdateTheme
.doOnNext(theme -> {
String systemVersion =
systemVersionSupplier.get().toStableVersion().toString();
String requires = theme.getSpec().getRequires();
if (!VersionUtils.satisfiesRequires(systemVersion, requires)) {
throw new UnsatisfiedAttributeValueException(
String.format(
"The theme requires a minimum system version of %s, "
+ "but the current version is %s.",
requires, systemVersion),
"problemDetail.theme.version.unsatisfied.requires",
new String[] {requires, systemVersion});
}
})
.delayUntil(theme -> {
var unstructureds = ThemeUtils.loadThemeResources(getThemePath(theme));
if (unstructureds.stream().filter(hasSettingsYaml(theme)).count() > 1) {
return Mono.error(
new IllegalStateException("Theme must only have one settings.yaml or settings.yml."));
}
if (unstructureds.stream().filter(hasConfigYaml(theme)).count() > 1) {
return Mono.error(
new IllegalStateException("Theme must only have one config.yaml or config.yml."));
}View on GitHub (pinned to d2f5165f9c)
Solutions
- Upgrade Halo to a version that satisfies the theme's spec.requires (the message reports both the required and current versions).
- Choose a theme version whose requires matches your Halo version.
- If you control the theme, edit theme.yaml spec.requires to a range your version satisfies and reinstall (only if the theme truly is compatible).
Example fix
# before (theme.yaml) # spec: # requires: ">=2.20.0" # fails on Halo 2.19 # after (only if the theme actually works on your version) # spec: # requires: ">=2.19.0"
Defensive patterns
Strategy: validation
Validate before calling
// Check version compatibility before installing/upgrading a theme:
String systemVersion = systemVersionSupplier.get().toStableVersion().toString();
String requires = newTheme.getSpec().getRequires();
if (!VersionUtils.satisfiesRequires(systemVersion, requires)) {
throw new IllegalStateException(
"Theme requires " + requires + " but Halo is " + systemVersion);
} Try / catch
try {
themeService.install(content).block();
} catch (UnsatisfiedAttributeValueException e) {
if ("problemDetail.theme.version.unsatisfied.requires".equals(e.getCode())) {
log.warn("Theme incompatible: requires {} but running {}",
e.getArguments()[0], e.getArguments()[1]);
}
throw e;
} Prevention
- Document and respect theme.spec.requires when distributing themes.
- Before installing, compare the theme's requires against your Halo version.
- Upgrade Halo first if a desired theme needs a newer version.
- Surface requires in the theme marketplace UI so users see compatibility up front.
When it happens
Trigger: Installing or upgrading a theme whose theme.yaml declares spec.requires (e.g. '>=2.20.0') while the running Halo version is older. The check fires in the doOnNext after createOrUpdateTheme, so the Theme CR may already be written before the exception propagates.
Common situations: Installing a theme built for a newer Halo on an older instance; downgrading Halo below a theme's requirement; theme author set an overly strict requires range.
Related errors
- Failed to unzip theme
- problemDetail.theme.install.missingManifest
- Invalid attachment
- User permissions not set in PermissionUtils
- ESM provider manifest must be an object.
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/d460a8e45c1c3989.
Report an issue: GitHub.