{"record":{"id":"05a58f57b2e025fc","repo":"hasura/graphql-engine","slug":"plugin-should-be-named-q-not-q","errorCode":null,"errorMessage":"plugin should be named %q, not %q","messagePattern":"plugin should be named %q, not %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/plugins/types.go","lineNumber":133,"sourceCode":"}\n\n// ValidatePlugin checks for structural validity of the Plugin object with given\n// name.\nfunc (p Plugin) ValidatePlugin(name string) error {\n\tvar op errors.Op = \"plugins.Plugin.ValidatePlugin\"\n\tif !IsSafePluginName(name) {\n\t\treturn errors.E(\n\t\t\top,\n\t\t\tfmt.Errorf(\n\t\t\t\t\"the plugin name %q is not allowed, must match %q\",\n\t\t\t\tname,\n\t\t\t\tsafePluginRegexp.String(),\n\t\t\t),\n\t\t)\n\t}\n\n\tif p.Name != name {\n\t\treturn errors.E(op, fmt.Errorf(\"plugin should be named %q, not %q\", name, p.Name))\n\t}\n\n\tif p.ShortDescription == \"\" {\n\t\treturn errors.E(op, \"should have a short description\")\n\t}\n\n\tif strings.ContainsAny(p.ShortDescription, \"\\r\\n\") {\n\t\treturn errors.E(op, \"should not have line breaks in short description\")\n\t}\n\n\tif len(p.Platforms) == 0 {\n\t\treturn errors.E(op, \"should have a platform specified\")\n\t}\n\n\tif p.Version == \"\" {\n\t\treturn errors.E(op, \"should have a version specified\")\n\t}\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/plugins/types.go#L115-L151","documentation":"ValidatePlugin verifies that the name recorded inside the plugin manifest (p.Name) matches the name argument the caller supplied. A mismatch means the manifest declares one name but was loaded/registered under another, which would break later name-based lookups and binary naming.","triggerScenarios":"Calling ReadPluginFromFile(name, ...) where the JSON manifest's \"name\" field differs from the name argument — e.g. loading a file named foo.json whose manifest says \"name\": \"bar\".","commonSituations":"Copying an existing plugin manifest and forgetting to update the name field; renaming the manifest file but not its contents; case mismatches between filename and manifest name.","solutions":["Make the manifest's \"name\" field exactly equal the name passed to ReadPluginFromFile (case-sensitive).","If the manifest name is correct, fix the name argument/file name you are loading with.","Re-validate after editing with ValidatePlugin before shipping."],"exampleFix":"// before\n// file: foo.json  { \"name\": \"bar\", ... }\np.ReadPluginFromFile(\"foo\")\n\n// after\n// file: foo.json  { \"name\": \"foo\", ... }\np.ReadPluginFromFile(\"foo\")","handlingStrategy":"validation","validationCode":"data, _ := os.ReadFile(path)\nvar probe struct{ Name string `json:\"name\"` }\nif err := json.Unmarshal(data, &probe); err != nil {\n\treturn err\n}\nif probe.Name != name {\n\treturn fmt.Errorf(\"manifest name %q != requested %q; fix manifest or name\", probe.Name, name)\n}","typeGuard":null,"tryCatchPattern":"if err := p.ValidatePlugin(name); err != nil {\n\tif strings.Contains(err.Error(), \"plugin should be named\") {\n\t\t// reconcile name argument with manifest \"name\" field, then retry\n\t}\n}","preventionTips":["Keep the manifest filename, its \"name\" field, and the name argument identical (case-sensitive).","Generate manifests from a template that injects the name once.","Lint manifests in CI with ValidatePlugin."],"tags":["plugins","validation","manifest","naming"],"backgroundTag":"manifest-field-mismatch","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}