{"record":{"id":"c865feefaf4816c0","repo":"puppetlabs/puppet","slug":"title-patterns-that-use-procs-are-not-supported","errorCode":null,"errorMessage":"title patterns that use procs are not supported.","messagePattern":"title patterns that use procs are not supported\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/generate/models/type/type.rb","lineNumber":48,"sourceCode":"          attr_reader :capability\n\n          # Initializes a type model.\n          # @param type [Puppet::Type] The Puppet type to model.\n          # @return [void]\n          def initialize(type)\n            @name = Puppet::Pops::Types::StringConverter.convert(type.name.to_s, '%p')\n            @doc = type.doc.strip\n            @properties = type.properties.map { |p| Property.new(p) }\n            @parameters = type.parameters.map do |name|\n              Property.new(type.paramclass(name))\n            end\n            sc = Puppet::Pops::Types::StringConverter.singleton\n            @title_patterns = type.title_patterns.to_h do |mapping|\n              [\n                sc.convert(mapping[0], '%p'),\n                sc.convert(mapping[1].map do |names|\n                  next if names.empty?\n                  raise Puppet::Error, _('title patterns that use procs are not supported.') unless names.size == 1\n\n                  names[0].to_s\n                end, '%p')\n              ]\n            end\n            @isomorphic = type.isomorphic?\n            # continue to emit capability as false when rendering the ERB\n            # template, so that pcore modules generated prior to puppet7 can be\n            # read by puppet7 and vice-versa.\n            @capability = false\n          end\n\n          def render(template)\n            template.result(binding)\n          end\n        end\n      end\n    end","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/generate/models/type/type.rb#L30-L66","documentation":"'puppet generate types' (run during r10k/Code Manager deploys for environment isolation) converts each resource type's title_patterns into a pcore type definition in generated Puppet code. A title pattern may bind regex captures to namevars via procs, but a proc cannot be rendered into the DSL, so generation aborts with Puppet::Error when any binding entry is a [name, proc] pair instead of a plain [name].","triggerScenarios":"An environment contains a native type whose self.title_patterns returns mappings like [[%r{^(.*)/(.*)$}, [[:user, proc { |s| s }], [:group, proc { |s| s }]]]] (entry size 2), and 'puppet generate types' runs — either manually or as a Code Manager/r10k post-deploy hook.","commonSituations":"Composite-namevar custom types (titles like 'path/line') in modules deployed to Puppet Enterprise with environment isolation; older module versions written before pcore support; upgrading Puppet 5.x to 6/7 where generate-types became a standard deploy step and the deploy starts failing.","solutions":["Upgrade the module to a version whose type supports pcore generation (many maintainers replaced proc-based title_patterns).","If the proc is a pass-through, patch the type to bind without a proc: [[:namevar]] instead of [[:namevar, proc { |s| s }]].","If the type genuinely needs capture transforms, report it to the maintainer and exclude the module from generate types until fixed.","Verify the fix by re-running 'puppet generate types' in the environment directory and checking the generated .pp."],"exampleFix":"# lib/puppet/type/foobar.rb - before\nnewtype(:foobar) do\n  def self.title_patterns\n    [[%r{^(.*)$}, [[:name, proc { |s| s }]]]]\n  end\nend\n\n# after\nnewtype(:foobar) do\n  def self.title_patterns\n    [[%r{^(.*)$}, [[:name]]]]\n  end\nend","handlingStrategy":"validation","validationCode":"# before `puppet generate types`, scan loaded types for proc title patterns\nrequire 'puppet'\n\nbad = Puppet::Type.loadall(Puppet::Node::Environment.remote('production'))\n  .map { |t| Puppet::Type.type(t) }\n  .flat_map { |t| (t.respond_to?(:title_patterns) ? t.title_patterns : []).map { |(_, binds)| binds } }\n  .flatten(1)\n  .select { |b| b.is_a?(Array) && b.size == 2 }\n\nabort 'types with proc title_patterns cannot be generated' unless bad.empty?","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Application[:generate].run_command('types')\nrescue Puppet::Error => e\n  raise if e.message !~ /title patterns that use procs/\n  warn \"skipping type generation: #{e.message}\"\nend","preventionTips":["Prefer single-namevar types; avoid composite title patterns in custom types.","Test 'puppet generate types' in CI for every environment that uses it at deploy time.","Keep modules current — pcore-compatible title_patterns is a maintained-module requirement."],"tags":["puppet","generate-types","pcore","namevar","code-generation"],"backgroundTag":"codegen-unsupported-feature","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}