{"record":{"id":"05606a0ad5957bdf","repo":"puppetlabs/puppet","slug":"could-not-find-request-to-destroy","errorCode":null,"errorMessage":"Could not find %{request} to destroy","messagePattern":"Could not find %(.+?) to destroy","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/memory.rb","lineNumber":16,"sourceCode":"# frozen_string_literal: true\n\nrequire_relative '../../puppet/indirector/terminus'\n\n# Manage a memory-cached list of instances.\nclass Puppet::Indirector::Memory < Puppet::Indirector::Terminus\n  def initialize\n    clear\n  end\n\n  def clear\n    @instances = {}\n  end\n\n  def destroy(request)\n    raise ArgumentError, _(\"Could not find %{request} to destroy\") % { request: request.key } unless @instances.include?(request.key)\n\n    @instances.delete(request.key)\n  end\n\n  def find(request)\n    @instances[request.key]\n  end\n\n  def search(request)\n    found_keys = @instances.keys.find_all { |key| key.include?(request.key) }\n    found_keys.collect { |key| @instances[key] }\n  end\n\n  def head(request)\n    !find(request).nil?\n  end\n\n  def save(request)","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/memory.rb#L1-L34","documentation":"The memory terminus (used in tests and short-lived in-process caches) keeps instances in a hash keyed by request.key. destroy raises ArgumentError 'Could not find <key> to destroy' unless the key was previously saved via save; unlike the disk termini it does not emulate success on missing entries, so double destroys fail loudly.","triggerScenarios":"Calling destroy twice for the same key; destroying after clear; rspec before/after hooks that both clean up; shared examples where the save step never ran.","commonSituations":"Test suites with double-running cleanup hooks; retry logic that assumes idempotent destroy; fixtures resetting state between hooks while the subject still holds stale references.","solutions":["Guard with find first: only destroy when terminus.find(request) returns a value.","Rescue ArgumentError when cleanup is best-effort (e.g. in test teardown).","Use clear to wipe all state instead of destroying keys one by one.","Fix hook ordering so cleanup does not execute twice for the same key."],"exampleFix":"# before\nafter { terminus.destroy(req) } # raises when the key was never saved / already destroyed\n\n# after\nafter { terminus.destroy(req) if terminus.find(req) }","handlingStrategy":"validation","validationCode":"req = Puppet::Indirector::Request.new(indirection.name, :destroy, key, nil)\nterminus.destroy(req) if terminus.find(req)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make test cleanup idempotent (find-before-destroy or clear).","Do not assume memory terminus destroy matches disk termini, which emulate success on missing entries.","Keep one cleanup owner per key in test harnesses."],"tags":["puppet","indirector","memory-terminus","testing","idempotency"],"backgroundTag":"key-not-found","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}