{"record":{"id":"bfad1a1aad0704e2","repo":"fluent/fluentd","slug":"implement-this-method-in-child-class-bfad1a","errorCode":null,"errorMessage":"Implement this method in child class","messagePattern":"Implement this method in child class","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"lib/fluent/plugin/storage.rb","lineNumber":62,"sourceCode":"\n      def synchronized?\n        false\n      end\n\n      def implementation\n        self\n      end\n\n      def load\n        # load storage data from any data source, or initialize storage internally\n      end\n\n      def save\n        # save internal data store into data source (to be loaded)\n      end\n\n      def get(key)\n        raise NotImplementedError, \"Implement this method in child class\"\n      end\n\n      def fetch(key, defval)\n        raise NotImplementedError, \"Implement this method in child class\"\n      end\n\n      def put(key, value)\n        # return value\n        raise NotImplementedError, \"Implement this method in child class\"\n      end\n\n      def delete(key)\n        # return deleted value\n        raise NotImplementedError, \"Implement this method in child class\"\n      end\n\n      def update(key, &block) # transactional get-and-update\n        raise NotImplementedError, \"Implement this method in child class\"","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/plugin/storage.rb#L44-L80","documentation":"Fluent::Plugin::Storage is the abstract base class for storage plugins; #get is declared but only raises NotImplementedError to force subclasses to override it. Calling storage.get(key) means the storage object's class never provided a concrete getter. Fluentd's built-in LocalStorage and other shipped storages override it, so this error almost always means a custom storage plugin is incomplete or the base class was instantiated directly.","triggerScenarios":"Calling storage.get('some_key') on an instance of a class that inherits Fluent::Plugin::Storage without overriding #get (lib/fluent/plugin/storage.rb:61-63). Instantiating Fluent::Plugin::Storage itself via Fluent::Plugin.new_storage('...') with a type that maps to the base class, or writing a custom storage plugin (registered with Fluent::Plugin.register_storage) that omits #get.","commonSituations":"Writing a custom storage plugin (e.g. Redis- or memcached-backed) and forgetting one of the CRUD methods; test code that exercises a half-finished storage subclass; a plugin author who copied the skeleton but left #get as a stub before shipping.","solutions":["Override #get(key) in your Fluent::Plugin::Storage subclass to return the value for the key from your backing store","If you did not intend to write a storage plugin, use a built-in implementation such as the default 'local' type (Fluent::Plugin::LocalStorage) instead of the base class","Cover the whole abstract API in your subclass: get, fetch, put, delete, and update (lines 61-81), plus load/save when persistence matters","In tests, stub the abstract methods or use a test double derived from LocalStorage instead of the raw base class"],"exampleFix":"// before (custom storage plugin, incomplete)\nclass MyStorage < Fluent::Plugin::Storage\n  Fluent::Plugin.register_storage('my', self)\n  def put(key, value)\n    @data[key.to_s] = value\n  end\nend\nstorage.get('counter')  # => NotImplementedError\n\n// after\nclass MyStorage < Fluent::Plugin::Storage\n  Fluent::Plugin.register_storage('my', self)\n  def put(key, value)\n    @data[key.to_s] = value\n  end\n\n  def get(key)\n    @data[key.to_s]\n  end\nend","handlingStrategy":"type-guard","validationCode":"storage = Fluent::Plugin.new_storage('my')\nraise 'storage does not implement #get' if storage.method(:get).owner == Fluent::Plugin::Storage","typeGuard":"def concrete_storage?(storage)\n  %i[get fetch put delete update].all? do |m|\n    storage.respond_to?(m) && storage.method(m).owner != Fluent::Plugin::Storage\n  end\nend","tryCatchPattern":"begin\n  storage.get('key')\nrescue NotImplementedError => e\n  logger.error(\"storage plugin is incomplete: #{e.message} (#{storage.class})\")\n  raise\nend","preventionTips":["When authoring a storage plugin, implement the full abstract API (get/fetch/put/delete/update) before registering it","Add a unit test that calls every abstract method on your storage class so omissions surface in CI, not production","Subclass Fluent::Plugin::LocalStorage and override only what differs, inheriting working CRUD defaults","Run fluentd --dry-run against the config to exercise plugin configuration before deployment"],"tags":["fluentd","storage","not-implemented","abstract-method","plugin-development"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}