{"record":{"id":"5efd2cc5b1cdffea","repo":"jdx/mise","slug":"inreplace-in-path-made-no-substitutions-the-f","errorCode":null,"errorMessage":"inreplace in #{path} made no substitutions — the formula may need updating","messagePattern":"inreplace in #(.+?) made no substitutions — the formula may need updating","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/shim.rb","lineNumber":777,"sourceCode":"\n  def inreplace(paths, before = nil, after = nil, audit_result = true, &block)\n    Array(paths).each do |path|\n      path = Pathname.new(path.to_s)\n      content = path.read\n      replaced = content.dup\n      if block\n        ext = InreplaceText.new(replaced)\n        block.call(ext)\n        replaced = ext.text\n      else\n        raise \"inreplace: missing before/after\" if before.nil?\n        case before\n        when Regexp then replaced.gsub!(before, after.to_s)\n        else replaced = replaced.gsub(before.to_s, after.to_s)\n        end\n      end\n      if audit_result && replaced == content\n        raise \"inreplace in #{path} made no substitutions — the formula may need updating\"\n      end\n      path.write(replaced)\n    end\n  end\n\n  def cd(path, &block) = Dir.chdir(path.to_s, &block)\n\n  def mkdir(name, &block)\n    path = Pathname.new(name.to_s)\n    path.mkpath\n    block ? Dir.chdir(path.to_s, &block) : path\n  end\n\n  def loader_path = OS.mac? ? \"@loader_path\" : \"$ORIGIN\"\n\n  def rpath(source: bin, target: lib)\n    \"#{loader_path}/#{Pathname.new(target.to_s).relative_path_from(Pathname.new(source.to_s))}\"\n  end","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/shim.rb#L759-L795","documentation":"inreplace audits its own result: if the file content after replacement is identical to before (audit_result enabled), the search pattern matched nothing. The shim raises to surface stale patches early — typically because upstream changed and the formula's search string no longer exists.","triggerScenarios":"The `before` string/regex no longer appears in the file (upstream refactor); the file path is empty or already rewritten; case/formatting drift in the target text; running inreplace twice on the same file.","commonSituations":"Version bumps where the edited config file changed format; formulas editing generated files whose content varies by platform or toolchain version; patches kept across many versions until they silently stop matching.","solutions":["Update the search string to match the current file content (inspect the file)","Read the target file to confirm the pattern exists and its exact spelling","Make the before pattern more tolerant (use a Regexp) or guard with a conditional inreplace only when needed","Ensure inreplace isn't applied twice to the same file in one install"],"exampleFix":"# before\ninreplace \"config.mk\", \"CC = gcc\", \"CC = #{ENV[\"CC\"]}\"\n# after\ninreplace \"config.mk\", /^CC\\s*=\\s*\\S+$/, \"CC = #{ENV[\"CC\"]}\"","handlingStrategy":"validation","validationCode":"content = File.read(path)\nraise \"pattern not found in #{path}\" unless content.include?(search)\ninreplace(path, search, replacement)","typeGuard":null,"tryCatchPattern":"begin\n  inreplace f, old, new\nrescue RuntimeError => e\n  raise unless e.message.include?(\"made no substitutions\")\n  warn \"formula needs updating: #{e.message}\"\nend","preventionTips":["Verify the search string exists in the file on every version bump","Use tolerant regexes instead of exact strings where formatting varies","Never run inreplace twice on the same content","Read the target file when updating a formula to refresh search patterns"],"tags":["ruby","inreplace","formula"],"backgroundTag":"no-substitution-made","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}