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

  1. Upgrade Halo to a version that satisfies the theme's spec.requires (the message reports both the required and current versions).
  2. Choose a theme version whose requires matches your Halo version.
  3. 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

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


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/d460a8e45c1c3989. Report an issue: GitHub.