Un estrany va arreglar el meu bug... però va arreglar la meitat equivocada i va funcionar

Un contribuïdor va corregir un bug en un servidor MCP de Safari. Però la meitat del seu pedaç no feia res. Descobreix la veritable lliçó sobre invariants

miércoles, 29 de julio de 2026 • 5 min de lectura • Equipo Q2BSTUDIO

La lección oculta en una corrección de código que parecía perfecta

Rebre una contribució externa sempre genera una certa expectació. Quan un desenvolupador aliè al teu projecte envia un pull request corregint un bug que tu mateix no havies detectat, la primera reacció sol ser de gratitud. Però quan t'asseus a analitzar el codi línia per línia, descobreixes que la meitat del pedaç no altera el comportament en absolut, mentre que l'altra meitat —la que l'autor amb prou feines va esmentar— és la que realment resol la fallada. Aquesta va ser l'experiència del responsable d'un servidor MCP per a Safari, i serveix com a lliçó magistral sobre com la manca de documentació d'invariants pot convertir el codi més innocent en una bomba de rellotgeria silenciosa.

L'escenari tècnic és un protocol de comunicació simple entre un procés Node.js i un helper natiu de Swift. Les peticions i respostes es correlacionen per ordre FIFO, sense identificadors únics. Una cua de callbacks espera les respostes, i cada resposta entrant s'assigna al primer callback de la cua. Aquest disseny funciona perfectament mentre cada sol·licitud enviada tingui una resposta pendent. Però si alguna sol·licitud s'abandona sense haver estat enviada realment —per exemple, per un error d'escriptura al pipe—, la cua es desincronitza de manera permanent. La resposta de la següent crida va a parar al callback zombi, i el veritable sol·licitant es queda esperant fins que salta el timeout. El símptoma mai és un error, sinó un penjament que pot passar desapercebut durant hores.

El contribuïdor, amb bon criteri, va identificar que calia gestionar aquells callbacks orfes. Va enviar un pedaç que modificava tres funcions idèntiques substituint el callback abandonat per un consumidor buit explícit. Això semblava sensat, però en analitzar el codi existent va resultar que el callback original ja es protegia a si mateix amb un flag booleà (resolved), així que la substitució era funcionalment idèntica. El veritable arranjament estava al bloc catch de l'escriptura, on l'autor del PR no només netejava el timeout sinó que eliminava l'entrada de la cua amb un splice. Aquella línia, gairebé oculta al diff, era la que impedia que l'error d'escriptura emverinés totes les crides posteriors. La resta del pedaç era un comentari que compila.

Allò fascinant d'aquest cas no és només que el col·laborador encertés la part correcta tot i descriure malament la solució, sinó que el mateix autor original del codi havia escrit el mateix patró set vegades al mateix fitxer. En quatre d'aquestes set funcions va incloure una línia defensiva —un consumidor buit per a respostes tardanes— però sense documentar per què era necessària. A les altres tres, aquella línia simplement no hi era, tot i que el bug d'escriptura existia a totes elles. L'absència d'una funció centralitzada que encapsulés l'invariant obligava a recordar una regla no escrita cada cop que s'afegia una nova crida al helper. El resultat era una ruleta russa: quatre de cada set vegades el desenvolupador recordava aplicar la defensa cosmètica, però la fallada real —la gestió de l'error d'escriptura— mai es va abordar en cap de les set.

A Q2BSTUDIO, empresa especialitzada en aplicacions a mida, sabem que el codi duplicat no és només un problema estètic. Cada còpia és una oportunitat perquè el següent desenvolupador —inclòs tu mateix mesos després— hagi de reconstruir mentalment les regles de negoci o els invariants del sistema. Quan aquestes regles no estan documentades, el risc d'introduir errors subtils es multiplica. I quan el sistema gestiona estats compartits que transcendeixen una sola crida, com passa en molts processos d'automatització o en sistemes de agents IA, una fallada de sincronització pot tenir conseqüències catastròfiques sense que ningú n'alci la veu.

La lliçó va més enllà d'aquest cas concret. El protocol sense IDs és només un exemple de com els dissenys simples poden amagar complexitats ocultes. En l'àmbit de la ciberseguretat, per exemple, un error de desincronització a l'autenticació pot derivar en accessos no autoritzats. En entorns cloud AWS/Azure, les cues de missatges mal gestionades poden provocar pèrdues de dades. Fins i tot en eines de BI/Power BI, la correlació incorrecta de consultes pot generar informes amb dades equivocades. L'arrel del problema és sempre la mateixa: un invariant no escrit que tothom assumeix però ningú ha formalitzat.

El veritable arranjament, tant en el cas del servidor MCP com en qualsevol projecte de programari, no és aplicar un pedaç puntual, sinó refactoritzar perquè la regla quedi explícita en un sol lloc. Una funció _helperRequest que centralitzi la lògica de timeout, error d'escriptura i neteja de cua elimina la dependència de la memòria humana. El col·laborador va corregir tres instàncies, però el deute tècnic seguia viu en l'estructura del fitxer. L'autor original va assumir la responsabilitat de fer aquella refactorització, reconeixent que el veritable bug no era a les línies que faltaven, sinó a l'absència d'un lloc on aquelles línies haguessin d'estar.

Aquest cas també ens recorda que les proves automatitzades no sempre cobreixen els escenaris de fallada més rellevants. Les 54 proves del projecte passaven totes, però cap simulava una ruptura del pipe de comunicació perquè aquest test no s'escriu fins que el bug ja ha ocorregut. A Q2BSTUDIO, en desenvolupar solucions de programari clau en mà, insistim a incorporar proves d'integració que exercitin els camins d'error i els estats compartits entre crides. Només així es pot reduir la bretxa entre allò que el codi hauria de fer i allò que realment fa quan les condicions són adverses.

Al final, l'anècdota del pull request que va arreglar la meitat equivocada ens deixa una reflexió valuosa: en el desenvolupament de programari, especialment quan treballem amb arquitectures distribuïdes, cues, agents autònoms o sistemes en temps real, documentar els invariants no és opcional. És tan important com el propi codi. I si a més aconseguim encapsular aquesta lògica en una única funció o mòdul, estarem protegint tots els futurs mantenedors —inclòs nosaltres mateixos— de cometre el mateix error una i altra vegada. Perquè, com demostra aquesta història, la memòria humana falla; el codi ben dissenyat no hauria de fer-ho.

¿UNA PAUSA?

Juega un momento antes de irte

NUESTROS SERVICIOS

Cómo podemos ayudarte

Tens un projecte en ment?

Explica'ns la teva visió i la convertim en una solució de programari. Sigui quin sigui l'abast, fem realitat la teva idea.