{"record":{"id":"fdf3a068eea33141","repo":"puppetlabs/puppet","slug":"parameters-cannot-be-added-after-a-block-parameter","errorCode":null,"errorMessage":"Parameters cannot be added after a block parameter","messagePattern":"Parameters cannot be added after a block parameter","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/functions.rb","lineNumber":535,"sourceCode":"    end\n\n    # Defines the return type. Defaults to 'Any'\n    # @param [String] type a reference to a Puppet Data Type\n    #\n    # @api public\n    def return_type(type)\n      unless type.is_a?(String) || type.is_a?(Puppet::Pops::Types::PAnyType)\n        raise ArgumentError, _(\"Argument to 'return_type' must be a String reference to a Puppet Data Type. Got %{type_class}\") % { type_class: type.class }\n      end\n\n      @return_type = type\n    end\n\n    private\n\n    # @api private\n    def internal_param(type, name, repeat = false)\n      raise ArgumentError, _('Parameters cannot be added after a block parameter') unless @block_type.nil?\n      raise ArgumentError, _('Parameters cannot be added after a repeated parameter') if @max == :default\n\n      if name.is_a?(String)\n        raise ArgumentError, _(\"Parameter name argument must be a Symbol. Got %{name_class}\") % { name_class: name.class }\n      end\n\n      if type.is_a?(String) || type.is_a?(Puppet::Pops::Types::PAnyType)\n        @types << type\n        @names << name\n        # mark what should be picked for this position when dispatching\n        if repeat\n          @weaving << -@names.size()\n        else\n          @weaving << @names.size() - 1\n        end\n      else\n        raise ArgumentError, _(\"Parameter 'type' must be a String reference to a Puppet Data Type. Got %{type_class}\") % { type_class: type.class }\n      end","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/functions.rb#L517-L553","documentation":"internal_param is the shared body behind param, optional_param, and the repeated forms. It rejects any parameter declared after a block parameter (@block_type set), because positional parameters bind before the trailing block in a Puppet dispatch. The error surfaces as ArgumentError at definition time.","triggerScenarios":"dispatch :m do block_param 'Callable', :block; param 'String', :x end. The param line after the block_param line raises immediately.","commonSituations":"Appending a new argument to an existing signature at the bottom of the block, under an existing block_param; reordering lines during cleanup.","solutions":["Move all positional param/optional_param declarations above the block_param line.","Treat block_param and optional_block_param as the last declaration in every dispatch block, always.","If a linter is available, enforce that ordering rule on function files."],"exampleFix":"# before\n dispatch :m do\n   block_param 'Callable', :block\n   param 'String', :x        # raises: parameter after block\n end\n\n# after: block parameter goes last\n dispatch :m do\n   param 'String', :x\n   block_param 'Callable', :block\n end","handlingStrategy":"validation","validationCode":"# CI grep: a param-style declaration after block_param in one dispatch block\n! grep -Pzo 'dispatch[^}]*block_param[^}]*\\n[^}]*\\s(param|optional_param|required_repeated_param|optional_repeated_param) ' lib/puppet/functions/**/*.rb","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fix the tail order once and forever: params, optional params, repeated param, block param.","Add new arguments at the top of the block, above block_param.","Keep dispatch blocks to a screenful so the ordering stays visible."],"tags":["puppet","functions","dispatch","parameter-order","dsl"],"backgroundTag":"parameter-order-invalid","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}