Mesrai
Back to blog
// essayTechnical Deep Dive

Deprecated Endpoint Re-Used in New Code: Mesrai's Removal Audit

Real PR catch: new feature calling @deprecated endpoint — blocks removal. Replacement call fix.

Mesrai TeamAugust 19, 20268 min read

A new invoice-PDF feature using the legacy document-get endpoint. The endpoint has been marked `@deprecated since v2.4` and is on the removal list for next quarter. Mesrai flagged it.

The vulnerable diff

tsservices/invoice-pdf.ts
// services/invoice-pdf.ts
import { api } from "../client";

export async function generateInvoicePDF(invoiceId: string) {
  // BUG: getDocument is @deprecated. Should use api.documents.get
  const doc = await api.legacy.getDocument(invoiceId);
  return renderPDF(doc);
}

// api/client.ts (the legacy method definition):
/**
 * @deprecated since v2.4 — use api.documents.get instead.
 * Will be removed in v3.0 (target: 2027-01).
 */
export const getDocument = (id: string) => fetch(`/api/legacy/documents/${id}`);

What is wrong

Deprecation works only if new code avoids deprecated APIs. Most JSDoc-based deprecations rely on IDE warnings that developers ignore or don't see. Without enforcement, the deprecation timeline keeps slipping because new callers keep appearing. The discipline is: every PR review checks for new uses of deprecated APIs, and the deprecation owner blocks PRs that add them.

The attack

Symptom:

textexploit
# Three quarters after deprecation:
$ grep -r "api.legacy.getDocument" src/ | wc -l
> 24 callers (added across 18 PRs since deprecation announced)

# Removal blocked indefinitely.

Compound cost — every new caller widens the migration the team will eventually have to do.

Mesrai's review comment

textreview-comment.txt
mesraipilot · Bot · reviewed 1 min ago

[mesrai] [code-review] [Logic] [Deprecated-API] [medium]

`api.legacy.getDocument` is marked @deprecated since v2.4 and is
on the removal list for v3.0 (2027-01). This PR adds a new caller.

Use the replacement:

  await api.documents.get(invoiceId);

If the replacement is missing functionality the legacy method
provides, flag the gap explicitly so the deprecation owner can
prioritize parity work — don't paper over by adding new callers.

To enforce: enable the TypeScript `@typescript-eslint/no-deprecated`
rule (recently stable). Mesrai will flag new uses regardless.

The fix

tsservices/invoice-pdf.ts (fixed)
// services/invoice-pdf.ts — fixed
import { api } from "../client";

export async function generateInvoicePDF(invoiceId: string) {
  const doc = await api.documents.get(invoiceId);
  return renderPDF(doc);
}

Use the canonical replacement. If feature parity is missing, file an issue rather than adding a deprecated caller.

Why human review missed it

Deprecation hygiene is hard to enforce without tooling. IDE warnings are ignored; lint rules are partial. Mesrai catches every new caller of an `@deprecated`-tagged API at PR time.

Related rules + further reading

Mesrai rule pack: logic/no-new-deprecated-callers — flags PRs that add new uses of @deprecated symbols.

TS-ESLint: @typescript-eslint/no-deprecated.

Common deprecation-debt source in long-lived codebases.

Takeaway

Deprecated means: no new callers. Mesrai blocks new ones at PR time, deprecation owner can plan removal.

// try

See it on your next PR.

Free for individuals. Install in two minutes. Mesrai reviews every commit.