evanw/esbuild · error

could not decode percent-escaped data

Error message

could not decode percent-escaped data: %s

What it means

When esbuild resolves a data: URL without the ;base64 flag, it calls url.PathUnescape on the payload to decode percent-encoded characters. This error fires when the data contains malformed percent-escape sequences such as a lone '%' or '%ZZ' (non-hex digits after the percent sign).

Solutions

  1. Ensure every '%' in the data URL is followed by exactly two hex digits (e.g. '%25' for a literal percent sign)
  2. Generate data URLs using encodeURIComponent or encodeURI to produce valid percent escapes
  3. Use base64 encoding instead of percent-encoding if the data contains many special characters

Example fix

// before
import x from 'data:text/javascript,console.log(50%)'
// after
import x from 'data:text/javascript,console.log(50%25)'
Defensive patterns

Strategy: validation

Validate before calling

function makeDataUrl(mimeType, content) {
  // encodeURIComponent produces valid percent-escapes
  return `data:${mimeType},${encodeURIComponent(content)}`
}
function isValidPercentEncoding(str) {
  return !/%[^0-9a-fA-F]|%[0-9a-fA-F][^0-9a-fA-F]/.test(str)
}
const url = makeDataUrl('text/javascript', 'export default 1')
// safe to import

Prevention

When it happens

Trigger: Importing a data: URL (without ;base64) containing a percent sign not followed by two hex digits, e.g. 'data:text/javascript,console.log(50%)'.

Common situations: Data URLs with literal percent signs (like in math expressions or formatting), truncated percent escapes, or data that was not properly URL-encoded.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/0c8ef6dcd3a50ffa. Report an issue: GitHub.

Appendix: source

Thrown at internal/resolver/dataurl.go:73

	default:
		return MIMETypeUnsupported
	}
}

func (parsed DataURL) DecodeData() (string, error) {
	// Try to read base64 data
	if parsed.isBase64 {
		bytes, err := base64.StdEncoding.DecodeString(parsed.data)
		if err != nil {
			return "", fmt.Errorf("could not decode base64 data: %s", err.Error())
		}
		return string(bytes), nil
	}

	// Try to read percent-escaped data
	content, err := url.PathUnescape(parsed.data)
	if err != nil {
		return "", fmt.Errorf("could not decode percent-escaped data: %s", err.Error())
	}
	return content, nil
}

View on GitHub (pinned to f6058f8364)