Skip to content

How to Fix URIError: malformed URI in JavaScript

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about How to Fix URIError: malformed URI in JavaScript. We cover key concepts, practical examples, and best practices.

The Problem

JavaScript throws URIError: malformed URI when decodeURI(), decodeURIComponent(), or encodeURI() receives an invalid URI string containing incomplete escape sequences or illegal characters.

Quick Fix

Step 1: Identify the invalid input

Passing a malformed percent-encoded string causes the error:

const decoded = decodeURIComponent('%');
URIError: URI malformed

The % character must be followed by two hex digits. Check the input:

const input = '%';
console.log('Input length:', input.length, 'First char code:', input.charCodeAt(0));

Step 2: Validate the string before decoding

Check for valid percent encoding before decoding:

function safeDecode(str) {
    if (typeof str !== 'string') return '';
    if (/%(?:[0-9A-Fa-f]{2})/.test(str) === false && str.includes('%')) {
        return str;
    }
    try {
        return decodeURIComponent(str);
    } catch {
        return str;
    }
}
console.log(safeDecode('%'));
console.log(safeDecode('hello%20world'));
%
hello world

Step 3: Use try/catch for URI operations

Always wrap decode operations in try/catch:

function safeURI(str) {
    try {
        return decodeURIComponent(str);
    } catch (e) {
        console.warn('Invalid URI input, returning raw string');
        return str;
    }
}
console.log(safeURI('%'));
console.log(safeURI('valid%20string'));
Invalid URI input, returning raw string
%
valid string

Step 4: Encode before passing to URI functions

Make sure you encode properly before decoding:

const raw = 'hello world';
const encoded = encodeURIComponent(raw);
console.log('Encoded:', encoded);
const decoded = decodeURIComponent(encoded);
console.log('Decoded:', decoded);
Encoded: hello%20world
Decoded: hello world

Prevention

  • Always wrap decodeURI and decodeURIComponent in try/catch blocks.
  • Validate input strings before URI decoding.
  • Use encodeURIComponent() for query parameters and encodeURI() for full URIs.
  • Never trust user-supplied URI strings from API responses or form inputs.

Common Mistakes with uri error

  1. Using return to exit a function early instead of wrapping a pure value in the monad
  2. Mixing let bindings with <- bindings in do notation, producing type errors
  3. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors

These mistakes appear frequently in real-world JS code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What is the difference between encodeURI and encodeURIComponent?

encodeURI() encodes a complete URI but preserves characters that are part of the URI syntax (:, /, ?, #). encodeURIComponent() encodes every character except letters, digits, and -_.!~*'(). Use encodeURIComponent() for query string values and encodeURI() for the full URI path.

Why does decodeURIComponent throw on input from user-generated content?

Users may type raw % signs, Unicode characters that are already malformed, or paste data from other sources. Always sanitize and validate inputs before passing them to decode functions. A try/catch wrapper is the safest approach.

Can I use btoa/atob for URI encoding instead?

No. btoa() and atob() handle Base64 encoding, not percent-encoding. They do not protect URI characters. For URL-safe Base64, replace + with - and / with _ after encoding, but for URI parameters always use encodeURIComponent().

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro