{"record":{"id":"32d4fed9fdd267c0","repo":"hashicorp/vagrant","slug":"commands-can-only-contain-letters-numbers-and-hy","errorCode":null,"errorMessage":"Commands can only contain letters, numbers, and hyphens","messagePattern":"Commands can only contain letters, numbers, and hyphens","errorType":"exception","errorClass":"Vagrant::Plugin::V1::InvalidCommandName","httpStatus":null,"severity":"error","filePath":"lib/vagrant/plugin/v1/plugin.rb","lineNumber":86,"sourceCode":"          # Return the list if we don't have a block\n          return hooks if !block_given?\n\n          # Otherwise add the block to the list of hooks for this action.\n          hooks << block\n        end\n\n        # Defines additional command line commands available by key. The key\n        # becomes the subcommand, so if you register a command \"foo\" then\n        # \"vagrant foo\" becomes available.\n        #\n        # @param [String] name Subcommand key.\n        def self.command(name=UNSET_VALUE, &block)\n          data[:command] ||= Registry.new\n\n          if name != UNSET_VALUE\n            # Validate the name of the command\n            if name.to_s !~ /^[-a-z0-9]+$/i\n              raise InvalidCommandName, \"Commands can only contain letters, numbers, and hyphens\"\n            end\n\n            # Register a new command class only if a name was given.\n            data[:command].register(name.to_sym, &block)\n          end\n\n          # Return the registry\n          data[:command]\n        end\n\n        # Defines additional communicators to be available. Communicators\n        # should be returned by a block passed to this method. This is done\n        # to ensure that the class is lazy loaded, so if your class inherits\n        # from or uses any Vagrant internals specific to Vagrant 1.0, then\n        # the plugin can still be defined without breaking anything in future\n        # versions of Vagrant.\n        #\n        # @param [String] name Communicator name.","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/plugin/v1/plugin.rb#L68-L104","documentation":"Plugin DSL validation in the v1 API: a name passed to the `command \"name\"` helper must match /^[-a-z0-9]+$/i — letters, digits, and hyphens only (lib/vagrant/plugin/v1/plugin.rb:86). Underscores, colons, spaces, or slashes raise Vagrant::Plugin::V1::Errors::InvalidCommandName at plugin definition time, i.e. when the plugin loads, before any command runs.","triggerScenarios":"A plugin's `class MyPlugin < Vagrant.plugin(\"1\")` block calling `command \"my_command\"`, `command \"ns:cmd\"`, or `command \"my command\" — the register call never happens because the name check fails first.","commonSituations":"Plugin authors porting rake-style namespaced names (colons) or Ruby underscore conventions into subcommand names; copying class names with `::` into the command key.","solutions":["Rename the subcommand to a hyphenated lowercase form: my_command -> my-command","Keep the gem name unchanged — only the subcommand key is validated","For grouping, use a hyphenated prefix scheme (myplug-list, myplug-add) instead of colons or underscores"],"exampleFix":"# before\nclass MyPlugin < Vagrant.plugin(\"1\")\n  name \"my plugin\"\n  command \"my_command\" do\n    require File.expand_path(\"../command\", __FILE__)\n    Command\n  end\nend\n\n# after\nclass MyPlugin < Vagrant.plugin(\"1\")\n  name \"my plugin\"\n  command \"my-command\" do\n    require File.expand_path(\"../command\", __FILE__)\n    Command\n  end\nend","handlingStrategy":"type-guard","validationCode":"COMMAND_NAME_RE = /\\A[-a-zA-Z0-9]+\\z/\nraise \"invalid command name '#{name}'\" unless name.to_s.match?(COMMAND_NAME_RE)","typeGuard":"# Ruby guard for the Vagrant command DSL (v1 and v2)\nCOMMAND_NAME_RE = /\\A[-a-zA-Z0-9]+\\z/\ndef valid_command_name?(name)\n  name.is_a?(String) && !name.empty? && name.match?(COMMAND_NAME_RE)\nend","tryCatchPattern":"begin\n  command \"my-command\" do\n    require_relative \"command\"\n    Command\n  end\nrescue Vagrant::Plugin::V1::Errors::InvalidCommandName => e\n  warn e.message # \"Commands can only contain letters, numbers, and hyphens\"\nend","preventionTips":["Use hyphens, never underscores or colons, when naming subcommands","Load the plugin class in its test suite — name errors surface at definition time","For generated plugins, derive the command key from a whitelisted-char template"],"tags":["plugin-development","validation","naming","v1-plugins"],"backgroundTag":"invalid-identifier","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}