{"record":{"id":"be700edf538573d0","repo":"instructure/canvas-lms","slug":"partitionmanager-can-only-work-on-models-that-are","errorCode":null,"errorMessage":"PartitionManager can only work on models that are Partitioned.\nSee CanvasPartman::Concerns::Partitioned.\n","messagePattern":"PartitionManager can only work on models that are Partitioned\\.\nSee CanvasPartman::Concerns::Partitioned\\.\n","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"gems/canvas_partman/lib/canvas_partman/partition_manager.rb","lineNumber":29,"sourceCode":"#\n# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY\n# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\n# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\n# details.\n#\n# You should have received a copy of the GNU Affero General Public License along\n# with this program. If not, see <http://www.gnu.org/licenses/>.\n\nrequire \"canvas_partman/partition_manager/by_date\"\nrequire \"canvas_partman/partition_manager/by_id\"\nrequire \"active_record/pg_extensions\"\n\nmodule CanvasPartman\n  class PartitionManager\n    class << self\n      def create(base_class)\n        unless base_class < Concerns::Partitioned\n          raise ArgumentError, <<~TEXT\n            PartitionManager can only work on models that are Partitioned.\n            See CanvasPartman::Concerns::Partitioned.\n          TEXT\n        end\n\n        const_get(base_class.partitioning_strategy.to_s.classify).new(base_class)\n      end\n    end\n\n    attr_reader :base_class\n\n    # Create partitions to hold existing data in a non-partitioned\n    # table, and n future partitions\n    #\n    # @param [Integer] advance\n    #   The number of partitions to create in advance\n    def create_initial_partitions(_advance = 1)\n      raise NotImplementedError","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/canvas_partman/lib/canvas_partman/partition_manager.rb#L11-L47","documentation":"CanvasPartman::PartitionManager.create builds a strategy object (Dynamic or Static) to manage partitions of a model. It only accepts model classes that include CanvasPartman::Concerns::Partitioned, because the manager relies on partitioning_strategy and related APIs. Passing a plain ActiveRecord class raises ArgumentError.","triggerScenarios":"Calling CanvasPartman::PartitionManager.create(SomeModel) where SomeModel does not `include CanvasPartman::Concerns::Partitioned` (or the mixin is included after the call).","commonSituations":"Forgetting the `include CanvasPartman::Concerns::Partitioned` line when adding a new partitioned table; using the manager against a shared base class; copy-pasting PartitionManager usage from another model.","solutions":["Add `include CanvasPartman::Concerns::Partitioned` to the model class","Verify you are passing the model class itself, not an instance or unrelated class","Ensure the model's migration creates the partitioned table matching its strategy"],"exampleFix":"// before\nclass QueuedMessage < ActiveRecord::Base; end\nPartitionManager.create(QueuedMessage)\n// after\nclass QueuedMessage < ActiveRecord::Base\n  include CanvasPartman::Concerns::Partitioned\nend\nPartitionManager.create(QueuedMessage)","handlingStrategy":"type-guard","validationCode":"raise ArgumentError unless MyModel.include?(CanvasPartman::Concerns::Partitioned)","typeGuard":"def partitioned_model?(klass) = klass.is_a?(Class) && klass < CanvasPartman::Concerns::Partitioned","tryCatchPattern":null,"preventionTips":["Include CanvasPartman::Concerns::Partitioned in every partitioned model","Centralize PartitionManager usage in helpers that assert the mixin first","Check model class definitions when adding new partitioned tables"],"tags":["ruby","activerecord","partitioning"],"backgroundTag":"invalid-argument-value","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}