Guía
Cómo corregir URIError: URI malformed en JavaScript
Localiza escapes porcentuales incompletos, bytes UTF-8 inválidos y sustitutos Unicode aislados que causan URI malformed.
por Tools in a Tab · Publicado el · Revisado el
Respuesta breve
URIError: URI malformed suele significar una de dos cosas: al decodificar,
hay un % incompleto o una secuencia de bytes que no es UTF-8; al codificar,
la cadena JavaScript contiene un sustituto Unicode aislado. No tapes el error
con un try/catch vacío: conserva la entrada, identifica la operación y corrige
la capa que produjo el valor.
Primero distingue codificación y decodificación
decodeURIComponent y decodeURI leen secuencias %HH. Fallan si encuentran
%, %A, %GG o bytes que no forman un carácter UTF-8 válido. Por ejemplo,
%E0%A4%A está truncado y no puede terminar la secuencia iniciada.
encodeURIComponent y encodeURI trabajan con texto Unicode. Pueden fallar si
la cadena contiene una mitad de par sustituto, algo posible al cortar una
cadena UTF-16 por índice o recibir datos internos corruptos.
El codificador y decodificador URL separa los modos componente, URL completa y valor de formulario, y devuelve diagnósticos sin enviar la entrada.
Escapes porcentuales incompletos
Cada % debe ir seguido exactamente por dos dígitos hexadecimales. %20 es un
espacio y %2F representa /; %2, %XZ y un % final no son escapes
válidos. Revisa la cadena original antes de sustituir % por %25, porque esa
operación puede convertir un dato roto en el texto literal de un escape roto.
Un error frecuente aparece al interpolar un porcentaje humano, como 50%, en
una URL y luego decodificarla. Si es parte de un valor, debe codificarse como
50%25 en el límite donde se construye ese componente.
Secuencias UTF-8 inválidas
Una serie de escapes puede tener pares hexadecimales correctos y seguir siendo
inválida. decodeURIComponent('%C3%28') falla porque C3 inicia una secuencia
UTF-8 de dos bytes, pero 28 no es un byte de continuación. No decodifiques
cada %HH directamente como un carácter Latin-1: reúne los bytes y aplica
UTF-8 de forma estricta.
MDN documenta ambos casos en la referencia de URI malformed error. La solución correcta suele estar en el productor que truncó o codificó con otra tabla de caracteres.
Sustitutos Unicode aislados al codificar
JavaScript almacena cadenas como unidades UTF-16. Muchos caracteres fuera del
plano básico, incluidos emojis, usan dos unidades llamadas par sustituto. Si
cortas justo entre ambas, queda un sustituto alto o bajo aislado que no
representa ningún valor Unicode válido; encodeURI puede lanzar URIError.
Evita truncar texto con slice() por unidades cuando debas respetar
caracteres. Iterar con Array.from(text) o for…of trabaja por puntos de código,
aunque secuencias visuales complejas pueden requerir segmentación de grafemas.
También puedes comprobar text.isWellFormed() cuando el entorno lo soporte.
Método de depuración
- Registra de forma segura si el fallo ocurre al codificar o decodificar, sin exponer datos sensibles.
- Para decodificación, busca el primer
%que no tenga dos hexadecimales. - Si la sintaxis es correcta, convierte todos los escapes a bytes y valida UTF-8.
- Para codificación, comprueba que la cadena Unicode esté bien formada.
- Confirma si la función debía actuar sobre un componente o la URL completa.
No apliques varias veces decodeURIComponent hasta que deje de cambiar. Cada
capa necesita una justificación contractual y una segunda pasada puede
convertir datos codificados en separadores activos.
Prevención
Mantén valores sin codificar dentro de la aplicación y codifícalos una sola
vez al insertarlos. Usa URL y URLSearchParams para construir direcciones,
valida entradas externas antes de decodificarlas y guarda pruebas con tildes,
emoji, %, secuencias truncadas y bytes inválidos. Un error visible es más
seguro que continuar con una URL cuyo significado haya cambiado.