{"record":{"id":"769e84438bd12d96","repo":"halo-dev/halo","slug":"plugin-name-must-not-be-blank","errorCode":null,"errorMessage":"Plugin name must not be blank","messagePattern":"Plugin name must not be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"application/src/main/java/run/halo/app/plugin/DefaultPluginGetter.java","lineNumber":24,"sourceCode":"import run.halo.app.core.extension.Plugin;\nimport run.halo.app.extension.ExtensionClient;\nimport run.halo.app.infra.exception.NotFoundException;\n\n/**\n * Default implementation of {@link PluginGetter}.\n *\n * @author guqing\n * @since 2.17.0\n */\n@Component\n@RequiredArgsConstructor\npublic class DefaultPluginGetter implements PluginGetter {\n    private final ExtensionClient client;\n\n    @Override\n    public Plugin getPlugin(String name) {\n        if (StringUtils.isBlank(name)) {\n            throw new IllegalArgumentException(\"Plugin name must not be blank\");\n        }\n        return client.fetch(Plugin.class, name).orElseThrow(() -> new NotFoundException(\"Plugin not found\"));\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":29,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/plugin/DefaultPluginGetter.java#L6-L29","documentation":"Thrown as IllegalArgumentException by DefaultPluginGetter.getPlugin when the supplied name is null, empty, or whitespace-only. The getter fetches a Plugin by name from the ExtensionClient; a blank name is a programmer error, not a not-found condition (not-found yields NotFoundException separately).","triggerScenarios":"Calling pluginGetter.getPlugin(name) with a blank/null name: an unvalidated request path variable, a missing form field, or a programmatic caller passing an uninitialized variable.","commonSituations":"A controller/endpoint forwarding an empty path variable; a frontend omitting the plugin name; a null returned from a lookup that is passed straight through; defensive code missing before delegating.","solutions":["Validate the name is non-blank before calling getPlugin and return 400 if it is.","Ensure the caller always supplies a populated plugin identifier.","Check upstream that the variable resolving the name is not null/empty."],"exampleFix":"// before\nPlugin p = pluginGetter.getPlugin(req.getName()); // name null\n\n// after\nif (!StringUtils.hasText(req.getName())) {\n    throw new ServerWebInputException(\"plugin name is required\");\n}\nPlugin p = pluginGetter.getPlugin(req.getName());","handlingStrategy":"validation","validationCode":"if (!StringUtils.hasText(name)) {\n    throw new ServerWebInputException(\"Plugin name is required\");\n}\nPlugin p = pluginGetter.getPlugin(name);","typeGuard":"static boolean isNonBlankPluginName(String s) {\n    return s != null && !s.trim().isEmpty();\n}","tryCatchPattern":"try {\n    pluginGetter.getPlugin(name);\n} catch (IllegalArgumentException e) {\n    throw new ServerWebInputException(\"Plugin name must not be blank\", null, e);\n} catch (NotFoundException e) {\n    return ServerResponse.notFound().build();\n}","preventionTips":["Validate path variables / request fields for non-blank plugin names at the controller boundary.","Never pass uninitialized or null name variables through to the getter.","Return 400 for blank input and 404 for unknown plugins separately."],"tags":["plugin","validation","api","bad-request"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}