{"record":{"id":"73b507417c171448","repo":"caddyserver/caddy","slug":"invalid-module-name-v","errorCode":null,"errorMessage":"invalid module name: %v","messagePattern":"invalid module name: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":84,"sourceCode":"}\n\nfunc cmdAddPackage(fl Flags) (int, error) {\n\tif len(fl.Args()) == 0 {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"at least one package name must be specified\")\n\t}\n\t_, nonstandard, _, err := getModules()\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"unable to enumerate installed plugins: %v\", err)\n\t}\n\tpluginPkgs, err := getPluginPackages(nonstandard)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, err\n\t}\n\n\tfor _, arg := range fl.Args() {\n\t\tmodule, version, err := splitModule(arg)\n\t\tif err != nil {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"invalid module name: %v\", err)\n\t\t}\n\t\t// only allow a version to be specified if it's different from the existing version\n\t\tif _, ok := pluginPkgs[module]; ok && (version == \"\" || pluginPkgs[module].Version == version) {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"package is already added\")\n\t\t}\n\t\tpluginPkgs[module] = pluginPackage{Version: version, Path: module}\n\t}\n\n\treturn upgradeBuild(pluginPkgs, fl)\n}\n\nfunc cmdRemovePackage(fl Flags) (int, error) {\n\tif len(fl.Args()) == 0 {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"at least one package name must be specified\")\n\t}\n\t_, nonstandard, _, err := getModules()\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"unable to enumerate installed plugins: %v\", err)","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L66-L102","documentation":"`caddy add-package` wraps splitModule's failure for one of its positional arguments: the argument's module-path portion (text before the last '@') is empty, so it cannot be added. The nested error is 'module name is required'.","triggerScenarios":"`caddy add-package @v1.0.0`, `caddy add-package @`, or an argument produced by an unset shell variable such that only the version part survives.","commonSituations":"Looping over a plugin list where one entry is malformed; pasting from release notes that show only `@version` suffixes.","solutions":["Identify the offending argument (each is validated in order; the first bad one aborts)","Rewrite it as a full Go module path, optionally with @version","Validate list entries before the loop: every item must match ^[^@\\s]+(@[^\\s]+)?$"],"exampleFix":"# before\nfor p in '@v1.2.3' 'github.com/mholt/caddy-ratelimit'; do caddy add-package \"$p\"; done\n\n# after\nfor p in 'github.com/caddy-dns/cloudflare@v0.2.1' 'github.com/mholt/caddy-ratelimit'; do caddy add-package \"$p\"; done","handlingStrategy":"validation","validationCode":"for p in \"$@\"; do [[ \"$p\" == @* || -z \"${p%%@*}\" ]] && { echo \"bad arg: $p\"; exit 1; }; done","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate plugin lists in scripts: every entry needs a non-empty path before the first '@'"],"tags":["caddy","add-package","argument-validation","cli"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}