{"record":{"id":"d460a8e45c1c3989","repo":"halo-dev/halo","slug":"problemdetail-theme-version-unsatisfied-requires","errorCode":"problemDetail.theme.version.unsatisfied.requires","errorMessage":"The theme requires a minimum system version of %s, but the current version is %s.","messagePattern":"The theme requires a minimum system version of (.+?), but the current version is (.+?)\\.","errorType":"exception","errorClass":"UnsatisfiedAttributeValueException","httpStatus":null,"severity":"error","filePath":"application/src/main/java/run/halo/app/theme/service/ThemeServiceImpl.java","lineNumber":209,"sourceCode":"     */\n    private Mono<Theme> persistent(Unstructured themeManifest, boolean isUpgrade) {\n        Assert.state(StringUtils.equals(Theme.KIND, themeManifest.getKind()), \"Theme manifest kind must be Theme.\");\n        var newTheme = Unstructured.OBJECT_MAPPER.convertValue(themeManifest, Theme.class);\n        final Mono<Theme> createOrUpdateTheme;\n        if (isUpgrade) {\n            createOrUpdateTheme = client.get(Theme.class, newTheme.getMetadata().getName())\n                    .doOnNext(theme -> updateTheme(theme, newTheme))\n                    .flatMap(client::update);\n        } else {\n            createOrUpdateTheme = client.create(newTheme);\n        }\n        return createOrUpdateTheme\n                .doOnNext(theme -> {\n                    String systemVersion =\n                            systemVersionSupplier.get().toStableVersion().toString();\n                    String requires = theme.getSpec().getRequires();\n                    if (!VersionUtils.satisfiesRequires(systemVersion, requires)) {\n                        throw new UnsatisfiedAttributeValueException(\n                                String.format(\n                                        \"The theme requires a minimum system version of %s, \"\n                                                + \"but the current version is %s.\",\n                                        requires, systemVersion),\n                                \"problemDetail.theme.version.unsatisfied.requires\",\n                                new String[] {requires, systemVersion});\n                    }\n                })\n                .delayUntil(theme -> {\n                    var unstructureds = ThemeUtils.loadThemeResources(getThemePath(theme));\n                    if (unstructureds.stream().filter(hasSettingsYaml(theme)).count() > 1) {\n                        return Mono.error(\n                                new IllegalStateException(\"Theme must only have one settings.yaml or settings.yml.\"));\n                    }\n                    if (unstructureds.stream().filter(hasConfigYaml(theme)).count() > 1) {\n                        return Mono.error(\n                                new IllegalStateException(\"Theme must only have one config.yaml or config.yml.\"));\n                    }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/theme/service/ThemeServiceImpl.java#L191-L227","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before (theme.yaml)\n#   spec:\n#     requires: \">=2.20.0\"   # fails on Halo 2.19\n# after (only if the theme actually works on your version)\n#   spec:\n#     requires: \">=2.19.0\"","handlingStrategy":"validation","validationCode":"// Check version compatibility before installing/upgrading a theme:\nString systemVersion = systemVersionSupplier.get().toStableVersion().toString();\nString requires = newTheme.getSpec().getRequires();\nif (!VersionUtils.satisfiesRequires(systemVersion, requires)) {\n    throw new IllegalStateException(\n        \"Theme requires \" + requires + \" but Halo is \" + systemVersion);\n}","typeGuard":null,"tryCatchPattern":"try {\n    themeService.install(content).block();\n} catch (UnsatisfiedAttributeValueException e) {\n    if (\"problemDetail.theme.version.unsatisfied.requires\".equals(e.getCode())) {\n        log.warn(\"Theme incompatible: requires {} but running {}\",\n            e.getArguments()[0], e.getArguments()[1]);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["theme","version","install","upgrade","semver"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}