ConstructiCat Logo
CodeBust.
Browse section ▾

Padrão Obsoleto ou Descontinuado.

Assistentes de IA emitem com confiança APIs, bibliotecas e expressões idiomáticas que eram atuais anos atrás, mas que agora estão descontinuadas, removidas ou substituídas, porque seu conhecimento paramétrico está congelado em um corte de treinamento e o padrão antigo ainda é o estatisticamente mais comum em seu corpus.

##Signs and Symptoms

Um revisor reconhece este smell quando o código gerado roda, mas combina com o estilo de um tutorial de dois ou três anos atrás: ele chama APIs sobre as quais o framework agora emite avisos, fixa versões principais antigas ou recorre a expressões idiomáticas legadas em vez da biblioteca padrão/sintaxe moderna. Sinais reveladores:

  • Avisos de descontinuação na instalação/build/execução que o modelo ignorou (DeprecationWarning, [DEP0005], componentWillMount is deprecated).
  • Expressões idiomáticas que antecedem a base atual da linguagem: var em vez de const/let, cadeias de callbacks/.then() onde a base de código usa async/await, require() em um projeto ESM, moment.js em vez de Intl/Temporal/date-fns.
  • Chamadas de biblioteca removidas na versão que você realmente tem instalada: pandas df.append(...) / .ix[], ciclos de vida legados do React, datetime.utcnow(), Node new Buffer(), url.parse().
  • Padrões de segurança legados que dominam dados de treinamento antigos: hashing MD5/SHA1, crypto.createCipher, SQL bruto concatenado por strings.
  • Reinventar o que a plataforma agora já fornece (deepClone, groupBy, UUID feitos à mão) em vez de structuredClone, Object.groupBy, crypto.randomUUID().
// Gerado por IA: compila, mas cada linha é um padrão agora descontinuado
const crypto = require('crypto');                 // projeto ESM usa import

const buf = new Buffer(userInput);                // Buffer() descontinuado desde o Node 6
const id  = crypto.createHash('md5')              // MD5 descontinuado para qualquer uso de segurança
              .update(token).digest('hex');
const cipher = crypto.createCipher('aes-256-cbc', key);  // API de caminho removido, KDF fraca

request(apiUrl, (err, res, body) => { /* ... */ });      // 'request' sem manutenção desde 2020

##Reasons for the Problem

Por que os modelos o produzem

  • Defasagem do corte de treinamento. O conhecimento paramétrico de um LLM está congelado em seu corte, mas as bibliotecas continuam evoluindo. Estudos que medem isso encontram uma taxa de uso de APIs descontinuadas de 25–38% em oito bibliotecas Python nas completações de LLMs (Wang et al., ICSE 2025), e mesmo os modelos de ponta atingem apenas 48–51% em geração condicionada à versão (GitChameleon 2.0). Não há consciência de API/versão em tempo real no momento da inferência.
  • A frequência do próximo token favorece o jeito antigo. O corpus contém anos de código legado, então a completação estatisticamente mais provável muitas vezes é a obsoleta. A OX Security observa que os modelos recorrem por padrão à concatenação de strings e a MD5/SHA1 justamente porque esses padrões "aparecem com mais frequência nos dados de treinamento", e a Veracode descobriu que os modelos escolhem a opção insegura/legada em ~45% das vezes quando lhes é dada uma escolha (OX Security).
  • Sem contexto do repositório. O modelo geralmente não sabe qual versão principal você realmente instalou, o que seu lockfile fixa, ou que lib/hash.ts já existe — então ele não consegue mirar na sua superfície de API. O enquadramento do Stack Overflow: um agente é "um ótimo reconhecedor de padrões… código bom entra, código bom sai" — sem um exemplo atual, ele recorre à média de seus dados de treinamento (Reyes Q&A).
  • Recompensa por "fazer funcionar" + bajulação. Os modelos otimizam para código que plausivelmente compila e satisfaz o prompt, não para "usa o caminho atual e suportado". A chamada descontinuada ainda funciona hoje, então ela parece correta.

Por que isso prejudica

  • Manutenibilidade / quebra-bomba-relógio. Descontinuado hoje significa removido na próxima versão principal — o código funciona até que uma atualização o quebre silenciosamente, e esses padrões são copiados e colados em vez de refatorados. A análise de 211M de linhas da GitClear mostra que as linhas copiadas/coladas subiram de 8,3%→12,3% enquanto as linhas refatoradas ("movidas") caíram de 24,1%→9,5% de 2020 a 2024, com blocos duplicados crescendo ~8x — então uma única expressão idiomática obsoleta se propaga em vez de ser corrigida uma única vez (GitClear 2025).
  • Correção. APIs substituídas muitas vezes têm semântica sutilmente diferente (utcnow() retorna um datetime ingênuo; ciclos de vida legados disparam em momentos diferentes), produzindo bugs que passam por um teste rápido de fumaça.
  • Segurança. Criptografia descontinuada (MD5, createCipher) e versões de pacotes desatualizadas carregam CVEs conhecidos que o modelo nunca confronta com nenhum banco de dados de advisories — um motivador central da constatação de que a maioria do código gerado por IA é entregue com pelo menos uma vulnerabilidade.
  • Carga de revisão & dívida técnica. Cada ocorrência é uma correção manual separada e, como o padrão é duplicado em vez de centralizado, o custo se acumula por toda a base de código.

##Treatment

Táticas de revisão & prompting

  • Declare as versões no prompt ou no contexto. "Estamos no React 19, pandas 2.2, Node 22 (ESM) — use apenas APIs atuais nessas versões." Traga a documentação atual para o contexto (um docs MCP / Context7) em vez de confiar na memória paramétrica.
  • Force uma passagem de ferramentas. Exija que o modelo execute o linter, o verificador de tipos e npm outdated / pip list --outdated, e então corrija todo aviso de descontinuação antes de declarar concluído. Avisos de descontinuação são o detector mais barato possível — não deixe que sejam ignorados.
  • Exija reutilização em vez de reinvenção. "Use o helper existente em lib/hash.ts; não faça hashing à mão." Aponte para o módulo canônico para que o modelo não regenere uma versão legada (Código Duplicado).
  • Codemods em vez de edições manuais. Para atualizações sistemáticas, execute os codemods/modernizadores oficiais em vez de pedir ao modelo que reescreva à mão: npx @next/codemod, codemods do React, regras pyupgrade/Ruff UP. Eles são determinísticos e completos.

A refatoração — isto é essencialmente Substituir Algoritmo / substituir-API-descontinuada, e consolidar as chamadas obsoletas duplicadas em um único helper aplica Extrair Função contra Código Duplicado:

// Antes — APIs de caminho descontinuado/removido
const buf    = new Buffer(userInput);
const id     = crypto.createHash('md5').update(token).digest('hex');
const cipher = crypto.createCipher('aes-256-cbc', key);

// Depois — atual, suportado, sensato em segurança
import crypto from 'node:crypto';

const buf    = Buffer.from(userInput);                 // construtor seguro
const id     = crypto.createHash('sha256').update(token).digest('hex');
const iv     = crypto.randomBytes(16);                 // IV explícito
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
// (para senhas, use argon2/bcrypt — não um hash bruto)

Para dependências, a correção equivalente é elevar o pin e deixar o codemod migrar os pontos de chamada, e então bloquear a deriva futura no CI (regra de lint abaixo + uma política Dependabot/Renovate) para que o modelo não possa reintroduzir silenciosamente o padrão antigo.

##Detected by

  • ESLint (eslint-plugin-n) n/no-deprecated-apiProíbe APIs principais descontinuadas do Node.js (Buffer(), crypto.createCipher, url.parse, etc.)
  • typescript-eslint @typescript-eslint/no-deprecatedSinaliza o uso de qualquer símbolo marcado como @deprecated em sua declaração JSDoc/TS
  • ESLint (eslint-plugin-react) react/no-deprecatedSinaliza APIs e métodos de ciclo de vida descontinuados do React (componentWillMount, etc.)
  • SonarQube / SonarSource RSPEC-1874 ("@Deprecated" code should not be used)Relata o uso de código anotado/marcado como descontinuado
  • Ruff pyupgrade (UP) rulesDetecta e reescreve expressões idiomáticas Python obsoletas/substituídas para equivalentes modernos
  • Dependabot version-updatesSinaliza versões de dependências desatualizadas (a faceta de pacote obsoleto deste smell)