{"record":{"id":"1eb5930660e3a37e","repo":"halo-dev/halo","slug":"unable-to-complete-the-request-because-the-plugin","errorCode":null,"errorMessage":"Unable to complete the request because the plugin configMapName is blank","messagePattern":"Unable to complete the request because the plugin configMapName is blank","errorType":"validation","errorClass":"ServerWebInputException","httpStatus":400,"severity":"warning","filePath":"application/src/main/java/run/halo/app/core/endpoint/console/PluginEndpoint.java","lineNumber":307,"sourceCode":"                                .response(responseBuilder().implementation(String.class)))\n                .build();\n    }\n\n    private Mono<ServerResponse> fetchPluginJsonConfig(ServerRequest request) {\n        final var name = request.pathVariable(\"name\");\n        return client.fetch(Plugin.class, name)\n                .mapNotNull(plugin -> plugin.getSpec().getConfigMapName())\n                .flatMap(settingConfigService::fetchConfig)\n                .flatMap(json -> ServerResponse.ok().bodyValue(json));\n    }\n\n    private Mono<ServerResponse> updatePluginJsonConfig(ServerRequest request) {\n        final var pluginName = request.pathVariable(\"name\");\n        return client.fetch(Plugin.class, pluginName)\n                .doOnNext(plugin -> {\n                    String configMapName = plugin.getSpec().getConfigMapName();\n                    if (!StringUtils.hasText(configMapName)) {\n                        throw new ServerWebInputException(\n                                \"Unable to complete the request because the plugin configMapName is blank\");\n                    }\n                })\n                .flatMap(plugin -> {\n                    final String configMapName = plugin.getSpec().getConfigMapName();\n                    return request.bodyToMono(ObjectNode.class)\n                            .switchIfEmpty(Mono.error(new ServerWebInputException(\"Required request body is missing\")))\n                            .flatMap(configMapJsonData ->\n                                    settingConfigService.upsertConfig(configMapName, configMapJsonData));\n                })\n                .then(ServerResponse.noContent().build());\n    }\n\n    Mono<ServerResponse> changePluginRunningState(ServerRequest request) {\n        final var name = request.pathVariable(\"name\");\n        return request.bodyToMono(RunningStateRequest.class)\n                .flatMap(runningState -> {\n                    var enable = runningState.isEnable();","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/core/endpoint/console/PluginEndpoint.java#L289-L325","documentation":"PluginEndpoint.updatePluginJsonConfig fetches the named plugin and, inside doOnNext, throws ServerWebInputException (HTTP 400) when the plugin's spec.configMapName is blank. Plugins only expose a JSON config editor when they declare a configMapName; without one there is no config to read or write, so the update cannot proceed.","triggerScenarios":"PUT/POST to the plugin JSON config endpoint for a plugin whose spec.configMapName is unset or empty — typically a plugin with no setting/configMap wired up, or a not-yet-fully-initialized plugin.","commonSituations":"Calling the JSON config endpoint on a plugin that has no settings defined; a plugin whose configMapName was cleared; UI showing the config editor for a non-configurable plugin.","solutions":["Confirm the plugin actually defines a Setting and has a configMapName set in its spec before calling the JSON config endpoint.","If you maintain the plugin, ensure spec.configMapName is populated when the plugin has settings.","On the client, hide the JSON config action for plugins whose configMapName is blank."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!StringUtils.hasText(plugin.getSpec().getConfigMapName())) {\n    return Mono.error(new ServerWebInputException(\n        \"Unable to complete the request because the plugin configMapName is blank\"));\n}","typeGuard":"static boolean pluginHasJsonConfig(Plugin p) {\n    return p != null && StringUtils.hasText(p.getSpec().getConfigMapName());\n}","tryCatchPattern":null,"preventionTips":["Hide the JSON config editor for plugins whose configMapName is blank.","As a plugin author, set configMapName when your plugin defines settings.","Check the plugin's Setting/configMapName before calling the endpoint."],"tags":["validation","plugin","config","http-400","precondition"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}