octobercms/october · error · ApplicationException
system::lang.media.invalid_path
Error message
system::lang.media.invalid_path
What it means
MediaLibrary::validatePath() rejects any path containing a Unicode category-C character (preg_match('/[\p{C}]/u')): control chars 0x00-0x1F and 0x7F-0x9F, format chars like zero-width space (U+200B), BOM (U+FEFF) and bidi/RTL override marks (U+200E, U+202E), plus surrogates and unassigned code points. These characters are invisible in listings but break rendering, sorting, matching, and remote storage keys, so the media library hard-rejects them.
Source
Thrown at modules/media/classes/MediaLibrary.php:500
* @return string
*/
public static function validatePath($path, $normalizeOnly = false): string
{
$path = str_replace('\\', '/', $path);
$path = '/'.trim($path, '/');
if ($normalizeOnly) {
return $path;
}
// Reject paths that are not valid UTF-8
if (!mb_check_encoding($path, 'UTF-8')) {
throw new ApplicationException(Lang::get('system::lang.media.invalid_path_encoding', ['path' => mb_scrub($path)]));
}
// Reject control, format and other invisible characters
if (preg_match('/[\p{C}]/u', $path)) {
throw new ApplicationException(Lang::get('system::lang.media.invalid_path', compact('path')));
}
// Reject characters reserved by file systems and URLs
if (preg_match('/[<>:"|?*]/', $path)) {
throw new ApplicationException(Lang::get('system::lang.media.invalid_path', compact('path')));
}
$regexDirectorySeparator = preg_quote('/', '#');
$regexDot = preg_quote('.', '#');
$regex = [
// Beginning of path
'(^'.$regexDot.'+?'.$regexDirectorySeparator.')',
// Middle of path
'('.$regexDirectorySeparator.$regexDot.'+?'.$regexDirectorySeparator.')',
// End of path
'('.$regexDirectorySeparator.$regexDot.'+?$)',View on GitHub (pinned to b608633a7e)
Solutions
- Strip category-C characters before calling the API: $path = preg_replace('/\p{C}/u', '', $path);
- For user-supplied names, sanitize aggressively on input (slugify or transliterate) instead of accepting raw pasted strings
- Paste the path into a hex viewer or use bin2hex() on the suspect segment to identify the exact invisible code point, then rename the file
Example fix
// before
$clean = MediaLibrary::validatePath($raw); // rejects zero-width chars
// after
$raw = preg_replace('/\p{C}/u', '', $raw);
$clean = MediaLibrary::validatePath($raw); Defensive patterns
Strategy: validation
Validate before calling
$path = preg_replace('/\p{C}/u', '', $path); // strip control/format/invisible chars
$clean = MediaLibrary::validatePath($path); Type guard
function hasInvisiblePathChars(string $path): bool {
return (bool) preg_match('/\p{C}/u', $path);
} Prevention
- Slugify user-supplied names on input so invisible characters never enter storage
- Audit bulk-import data (CSV/Excel) for zero-width and bidi marks before import
- Treat invisible-character payloads as hostile — they often mask extension tricks
When it happens
Trigger: Filenames copy-pasted from web pages, PDFs, or word processors that embed zero-width characters; crafted names using RTL-override to disguise the real extension; paths containing literal tab/newline; a UTF-8 BOM prefixed to the first segment.
Common situations: Bulk imports from CSV/Excel with unclean data; user complaints that a file 'looks fine' but the media manager rejects it; security scanners probing with bidi tricks.
Related errors
- system::lang.media.invalid_path_encoding
- cms::lang.asset.invalid_name
- editor::lang.filesystem.invalid_path
- backend::lang.media.type_blocked
- Media tags can only be processed for front-end requests.
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/ccd3b49129f0c598.
Report an issue: GitHub.