ErrLookup › Background articles › "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release
"is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release
"is deprecated and will be removed" warnings appear when your code still calls a library API — a renamed class, an old keyword argument, a legacy option — that the library kept working for one release but plans to delete. These warnings span Ruby (Spree, Falcon, Capistrano, Grape, HTTParty, Winston), JavaScript (Astro, Angular, Nuxt, CopilotKit, SvelteKit), and other stacks; most are safe today but become hard errors (NameError, ArgumentError, removal) in the next major version, so the fix is to migrate to the named replacement now and run your suite with deprecations raised.
Distilled from 96 documented records across 29 repositories.
Background
This family covers the soft half of an API lifecycle: a library has renamed, re-contracted, or scheduled the removal of an API and keeps the old path alive for exactly one release window. The warning is the migration notice. What unifies the records is the shape — the message names the deprecated symbol, states the release that removes it (Spree 6.1, winston@4, Nuxt 5+, Astro 7), and points at the replacement — while the behavior varies from a pure rename to a silently degraded call.
Mechanically, the warnings are emitted from the library's own seam code, not from the language runtime. Spree wraps deprecated writers and workflow keywords in deprecation-aware accessors that warn then delegate or stash; Grape's error? detects a legacy three-key Hash return shape and warns via Grape.deprecator; HTTParty warns from inside Response#nil? on every invocation; Astro's mocked Astro global inside getStaticPaths logs a console.warn in the property getter itself; Handsontable looks the message up in a DEPRECATED_HOOKS map; CopilotKit and Archon route through shared helpers that warn once per key and suppress in production. Some libraries even tell you where the call came from — Nuxt embeds the caller's file:line, HTTParty appends the trace line — and a few offer an enforcement knob: Grape.deprecator.behavior = :raise, Spree::Deprecation set to :raise, Node's --pending-deprecation.
Critically, 'deprecated' does not always mean 'still fully works'. Three behaviors coexist across the family. Pure renames keep working: Spree's Taxons::RemoveProducts shim delegates to Categories::RemoveProducts, and Falcon's Server.middleware forwards to rack_middleware. Keyword-rename shims translate and proceed: Spree's Carts::AddItem does cart ||= order; Fulfillments::Update falls back to fulfillment || shipment. But some deprecated paths silently degrade: Spree's Spree::Dependencies legacy workflow writers stash the override in legacy_workflow_overrides and the new code never consults it, so customized behavior quietly stops being used; winston's options.stream not only warns but throws if combined with filename or maxsize. You cannot assume the warning is cosmetic — each library differs.
Removal is the real deadline. Most records announce the version where the old path dies and what happens then: Spree 6.1 turns legacy constants into NameError and legacy keywords into unknown-keyword ArgumentError, Astro's getters are marked to throw in Astro 7, Angular will delete JSONP support entirely, and winston will drop the option in v4. Until then the old path usually keeps running — Capistrano's validator only warns, Falcon still invokes the legacy supervisor hook — which is why these warnings are easy to ignore right up to the upgrade that breaks boot, deploys, or checkout.
Common causes
- Calling a renamed class, module, or constant kept as a shim. Spree renames Taxons::RemoveProducts to Categories::RemoveProducts, Metafields to HasCustomFields, NumberGenerator to the has_spree_number macro; CopilotKit renames BasicAgent to BuiltInAgent. The old name still delegates and warns on every use, then disappears in the next major (NameError once removed).
- Passing legacy keyword arguments to a re-contracted service or workflow. After Spree 6.0's Cart/Order split, calls like Spree::Carts::AddItem.call(order: ...) or Fulfillments::Update.call(shipment: ...) still work via fallbacks but warn, and raise unknown-keyword ArgumentError in Spree 6.1. The same pattern hits Grape's parameter DSL, where a trailing positional options Hash (requires :id, { type: Integer }) is deprecated in favor of keyword arguments under Ruby 3.
- Initializer or boot-time configuration using an old seam name. Warnings fire at load time when initializers set legacy keys: Spree::Dependencies legacy *_service writers, Spree.queues.stock_location_stock_items=, or Capistrano's set :git_strategy. Because Spree's queues object is OpenStruct-like, a stale name can silently configure a field nobody reads.
- A stale dependency, extension, or gem forwarding the old API. The call site is not yours: an extension sets Capistrano strategy variables during load, a gem calls Falcon::Server.middleware, or an old service object forwards order: to Spree workflows. Fix by upgrading the dependency or patching its call site.
- Using a removed-in-future option or transport. Some deprecations remove capability rather than rename it: winston's File transport options.stream (use transports.Stream), Angular's JSONP support (XSS risk; use CORS-backed http.get), Astro's Astro.site / Astro.generator reads inside getStaticPaths (use import.meta.env.SITE or ASTRO_VERSION).
- Assuming a deprecated writer still routes. The dangerous case: Spree's fourteen legacy Spree::Dependencies workflow writers stash the value in legacy_workflow_overrides and the override is never applied to the new workflow seam, so customized cart, payment, and fulfillment behavior silently stops being consulted while legacy readers keep old code working.
- A dev-only test or spec helper on its way out. Spree's OrderWalkthrough spec helper warns per call and is replaced by purpose-built cart factories (:cart_ready_for_delivery, :cart_ready_to_complete, :completed_order_with_totals); SvelteKit's pushState is replaced by goto(url, { state, shallow: true }). These warn in test/dev output only but block the removal-version upgrade.
What usually fixes it
- Migrate to the named replacement now, while the old path still works: the warning text (or the linked upgrade guide, like Capistrano's UPGRADING-3.7.md) names the new class, keyword, hook, or option — port call sites in the same PR that bumps the library rather than deferring to the removal release.
- Sweep and centralize call sites: grep the repo for the deprecated name (app, lib, config, spec), route usage through one wrapper or helper so future renames are one-line fixes, and keep configuration overrides in a single initializer.
- Raise deprecations in test and CI so a straggler fails loudly instead of logging: Spree::Deprecation behavior :raise, Grape.deprecator.behavior = :raise, warnings-as-errors on JS builds, ruby -w / --pending-deprecation, and CI greps for known-banned patterns.
- After upgrading a library, boot once with warnings visible and read the output — load-time warnings name the offending class or file:line (Spree's Metafields warning embeds the includer, Nuxt embeds the caller) — and confirm the new seam actually took effect, since some deprecated writers stash instead of applying.
- Treat 'still works' as a bridge, not a guarantee: verify behavior after migrating, especially where the old and new contracts differ (Spree services became Workflow classes with different keyword vocabularies; a legacy service class is not interchangeable with its workflow replacement).
- For unavoidable interim use, pin versions and use the library's silencing or persistence escape hatch deliberately (CopilotKit's suppressDeprecationWarnings, Archon's copy-into-.archon/workflows stopgap) — as a stopgap with a migration deadline, not a plan.
Documented occurrences
- Spree::Dependencies##{legacy}= is deprecated and NO LONGER CONSULTED by Spree — the override was not applied. Port the class to the #{current} contract and set #{current}= instead. The #{legacy} name is removed in Spree 6.1. (spree/spree)
- Async::Container::Supervisor is replaced by Async::Service::Supervisor, please update your service definition. (socketry/falcon)
- [DEPRECATION] HTTParty will no longer override `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: https://github.com/jnunemaker/httparty/issues/568 #{trace_line} (jnunemaker/httparty)
- Calling Spree::Carts::AddItem with order: is deprecated and will be removed in Spree 6.1. Pass cart: instead. (spree/spree)
- Calling Spree::Carts::Recalculate with order: is deprecated and will be removed in Spree 6.1. Pass cart: instead. (spree/spree)
- Spree::Core::NumberGenerator is deprecated and will be removed in Spree 6.1. Replace `include Spree::Core::NumberGenerator.new(prefix: '#{@prefix}')` with `has_spree_number prefix: '#{@prefix}'`. See docs/plans/6.0-document-numbers.md. (spree/spree)
- Returning or throwing a Hash from a rescue handler is deprecated. Use `error!(...)` or a `Grape::Exceptions::ErrorResponse` instead. (ruby-grape/grape)
- [Deprecation Warning] #{key} is deprecated and will be removed in Capistrano 3.7.0.\nhttps://github.com/capistrano/capistrano/blob/master/UPGRADING-3.7.md (capistrano/capistrano)
- Spree::Dependencies##{legacy}= is deprecated and will be removed in Spree 6.1. Use #{current}= instead. (spree/spree)
- `Falcon::Server.middleware` is deprecated, use `.rack_middleware` instead. (socketry/falcon)
- Astro.site inside getStaticPaths is deprecated and will be removed in a future major version of Astro. Use import.meta.env.SITE instead (withastro/astro)
- Calling Spree::Fulfillments::Update with shipment:/shipment_attributes: keywords is deprecated and will be removed in Spree 6.1. Use fulfillment:/fulfillment_attributes: instead. (spree/spree)
- JSONP support is deprecated as it can cause XSS vulnerabilities, and will be removed in a future version of Angular. Please use standard HTTP requests instead. (angular/angular)
- ⚠️ `${workflow.name}` is deprecated and will be removed in an upcoming release. ${workflow.deprecated.message} To keep using this workflow after removal, copy the workflow file into your project `.archon/workflows/` or your global `~/.archon/workflows/`. (coleam00/Archon)
- [CopilotKit] Deprecation: ${message} (CopilotKit/CopilotKit)
- Spree::Taxons::RemoveProducts is deprecated and will be removed in Spree 6.1. Use Spree::Categories::RemoveProducts instead. (spree/spree)
- include Spree::Metafields is deprecated and will be removed in Spree 6.1. Use include Spree::HasCustomFields instead (#{name}). (spree/spree)
- Astro.generator inside getStaticPaths is deprecated and will be removed in a future major version of Astro. (withastro/astro)
- BasicAgent is deprecated, use BuiltInAgent instead (CopilotKit/CopilotKit)
- Passing a positional options Hash to `#{method_name}` is deprecated. Pass keyword arguments instead. (ruby-grape/grape)
…and 76 more across the corpus — use search.
Honest provenance: generated on 2026-09-03 from AI-assisted analysis of the linked records. See how records are made.