{"record":{"id":"50de4638709c2e98","repo":"Shopify/liquid","slug":"undefined-filter-method","errorCode":null,"errorMessage":"undefined filter #{method}","messagePattern":"undefined filter #(.+?)","errorType":"exception","errorClass":"Liquid::UndefinedFilter","httpStatus":null,"severity":"error","filePath":"lib/liquid/strainer_template.rb","lineNumber":54,"sourceCode":"        subclass.instance_variable_set(:@filter_methods, @filter_methods.dup)\n      end\n\n      def filter_method_names\n        filter_methods.map(&:to_s).to_a\n      end\n\n      private\n\n      def filter_methods\n        @filter_methods ||= Set.new\n      end\n    end\n\n    def invoke(method, *args)\n      if self.class.invokable?(method)\n        send(method, *args)\n      elsif @context.strict_filters\n        raise Liquid::UndefinedFilter, \"undefined filter #{method}\"\n      else\n        args.first\n      end\n    rescue ::ArgumentError => e\n      raise Liquid::ArgumentError, e.message, e.backtrace\n    end\n  end\nend\n","sourceCodeStart":36,"sourceCodeEnd":63,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/strainer_template.rb#L36-L63","documentation":"`StrainerTemplate#invoke` raises Liquid::UndefinedFilter when `context.strict_filters` is enabled and a template references a filter that is not registered/invokable. Without strict_filters, unknown filters are no-ops returning the first argument; in strict mode Liquid fails fast to surface typos and missing registrations.","triggerScenarios":"Rendering `{{ x | my_custom_filter }}` (or a typo'd built-in) with strict_filters: true while the filter module has not been added via `Liquid::Template.register_filter` or is not in the environment's filter registry.","commonSituations":"Enabling strict_filters in production after developing without it; custom filters registered on a different Liquid::Environment/Template instance than the one rendering; typos like `upcase` vs `upcase_first`; upgrading Liquid where a filter was renamed or removed.","solutions":["Register the missing filter: `Liquid::Template.register_filter(MyFilter)` (or add it to the Environment's filters).","Fix the filter name typo in the template.","Verify the filter is registered on the same environment/template instance that renders the document.","Disable strict_filters if undefined filters should be tolerated (returns the input unchanged).","Run template linting with strict_filters in CI to catch unknown filter usage before production."],"exampleFix":"// before\nLiquid::Template.parse(src).render( assigns, strict_filters: true ) # filter never registered\n// after\nLiquid::Template.register_filter(MyFilter)\nLiquid::Template.parse(src).render( assigns, strict_filters: true )","handlingStrategy":"validation","validationCode":"# before render (strict mode)\nused = src.scan(/\\|\\s*(\\w+)/).flatten\nmissing = used.uniq - Liquid::StrainerTemplate.send(:filter_methods).to_a\nraise \"unknown filters: #{missing}\" unless missing.empty?","typeGuard":"def filters_registered?(names)\n  names.all? { |n| Liquid::StrainerTemplate.send(:filter_methods).include?(n.to_s) }\nend","tryCatchPattern":"begin\n  template.render(assigns, strict_filters: true)\nrescue Liquid::UndefinedFilter => e\n  log_and_render_with_fallback\nend","preventionTips":["Register every custom filter on the same environment used for rendering","Enable strict_filters in CI linting to catch typos early","Keep a documented registry of available filters for template authors","Re-audit filter names after Liquid version upgrades"],"tags":["liquid","undefined-filter","strict-filters","template"],"backgroundTag":"resource-not-found","analyzedSha":"807d45a6b3d4568e64e86b375e3702df2c7c860c","analyzedAt":"2026-09-08T11:31:38.917Z","contentChangedAt":"2026-09-08T11:31:38.917Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}