Skip to content

Runs of statements that recur, verbatim, in multiple files. Likely copy-paste — extract a shared helper. Canonicalisation maps identifier tokens to per-window local indices so renamed copies still match; a block that is otherwise identical but carries different string or number literal values is not this check's concern — it is reported separately, at low severity, by Refactor.NearDuplicateBlock, since a near-clone is a weaker and noisier signal than a byte-identical one and should not trip a default CI gate on its own. The normalize_literals option controls which of the two checks a given block lands on (see that page), not whether it is reported at all. import declarations and re-exports (export { x } from './y') are never windowed at all — an import block can't be extracted into a shared helper, so treating one run of imports as a duplicate of another is never actionable, and normalizing their module-specifier string literals would otherwise make every same-length import block in a project match every other. A plain export { x } or export function f() {} (no source) is ordinary code and is unaffected. Minimum window is 6 consecutive statements (and 80 characters) to keep noise low. Cross-file: per-file run writes fingerprints into a corpus slot shared with Refactor.NearDuplicateBlock; finalize groups by hash, runs one overlap-claim pass across both checks' candidates together (so the two never report overlapping spans), and emits one Issue per verbatim-duplicate set with related spans pointing at every other occurrence.

ts
// src/orders.ts:42
const items = parseItems(input);
const validated = validateItems(items);
const priced = priceItems(validated, currency);
const taxed = applyTax(priced, region);
const total = sumItems(taxed);
return { items: taxed, total };
ts
// src/quotes.ts:88 — same shape, renamed: flagged as related
const products = parseItems(input);
const checkedProducts = validateItems(products);
const pricedProducts = priceItems(checkedProducts, currency);
const taxedProducts = applyTax(pricedProducts, region);
const total = sumItems(taxedProducts);
return { items: taxedProducts, total };
ts
// fix: extract once
export function pipeline(input: RawInput, currency: Currency, region: Region) {
  const items = parseItems(input);
  const validated = validateItems(items);
  const priced = priceItems(validated, currency);
  const taxed = applyTax(priced, region);
  return { items: taxed, total: sumItems(taxed) };
}

Suppressing: each duplicate group is emitted as a single Issue covering every occurrence — one primary location plus related spans for the rest. A cofferdam-ignore: Refactor.DuplicateBlock comment placed at any occurrence (the primary one or any related one) suppresses the whole finding, not just that copy. You don't need to find and suppress every occurrence individually — one ignore comment on either side of a duplicated pair is enough. Suppression targets the comment's next non-blank line, not a range, so anchor it to the first statement of the duplicated run — not to an import or other declaration preceding it. Import and re-export statements are excluded from windows entirely, so a comment sitting above one no longer covers the block that follows.

MIT License