{"record":{"id":"ec85f72dbb113256","repo":"puppetlabs/puppet","slug":"cannot-transform-object-of-class-klass","errorCode":null,"errorMessage":"Cannot transform object of class %{klass}","messagePattern":"Cannot transform object of class %(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/evaluator/collector_transformer.rb","lineNumber":171,"sourceCode":"\n  def query_LiteralNumber(o, scope)\n    @@evaluator.evaluate(o, scope)\n  end\n\n  def query_LiteralUndef(o, scope)\n    nil\n  end\n\n  def query_QualifiedName(o, scope)\n    @@evaluator.evaluate(o, scope)\n  end\n\n  def query_ParenthesizedExpression(o, scope)\n    query(o.expr, scope)\n  end\n\n  def query_Object(o, scope)\n    raise ArgumentError, _(\"Cannot transform object of class %{klass}\") % { klass: o.class }\n  end\n\n  def match_AccessExpression(o, scope)\n    pops_object = @@evaluator.evaluate(o, scope)\n\n    # Convert to Puppet 3 style objects since that is how they are represented\n    # in the catalog.\n    @@evaluator.convert(pops_object, scope, nil)\n  end\n\n  def match_AndExpression(o, scope)\n    left_match = match(o.left_expr, scope)\n    right_match = match(o.right_expr, scope)\n    [left_match, 'and', right_match]\n  end\n\n  def match_OrExpression(o, scope)\n    left_match = match(o.left_expr, scope)","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/evaluator/collector_transformer.rb#L153-L189","documentation":"Raised by CollectorTransformer#query_Object, the fallback handler for a collector search expression whose node class has no dedicated query_ translator. Collector queries (<| ... |>) support only a small grammar — comparisons (==/!=/and/or/not), tag checks, parenthesized expressions, and qualified names; anything else (function calls, arithmetic, literal structures) reaches query_Object and is rejected with the offending class name.","triggerScenarios":"`<| title == regsubst('a','b','c') |>`, `<| (foo + 1) == 3 |>`, `<| defined(File) |>` — any CallExpression, ArithmeticExpression, or other unsupported node occupying a query-grammar position inside `<| ... |>` or `Type<| ... |>`.","commonSituations":"Trying to make collection searches 'dynamic' by calling functions or computing values inline; porting complex SQL-like filters into collectors; assuming general Puppet expressions are valid inside collector brackets.","solutions":["Precompute values into variables and compare against them: `$wanted = regsubst('a','b','c')` then `<| title == $wanted |>`.","Restructure the query to use only supported operators: ==, !=, and, or, not, and `tag` comparisons.","For logic too complex for collectors, collect broadly and filter in a loop over the collected resources instead."],"exampleFix":"# before\nFile<| title == regsubst('base','prod','stage') |>   # Cannot transform object of class Puppet::Pops::Model::CallExpression\n\n# after\n$wanted = regsubst('base','prod','stage')\nFile<| title == $wanted |>","handlingStrategy":"validation","validationCode":"# Precompute every dynamic operand, then keep the query grammar pure:\n$wanted = regsubst('base','prod','stage')\nFile<| title == $wanted |>","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict collector queries to ==, !=, and, or, not and tag comparisons.","Hoist function calls/arithmetic into variables outside the <| ... |> brackets.","For complex predicates, collect broadly and filter in normal Puppet code afterwards."],"tags":["puppet","collectors","query","expression","dsl"],"backgroundTag":"unsupported-query-expression","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}