Saltar al contenido
Aback Tools Logo

Arreglar InvalidCharError en el Sanitizador de Nombres de Archivo de Python

Qué desencadena InvalidCharError de Python en los sanitizadores de nombres de archivo: caracteres ilegales por SO, el problema de los dos puntos en las marcas de tiempo, receta de sanitizador manual en Python, reglas multiplataforma y herramientas de validación gratuitas.

DH
Tutorials & How-Tos11 min de lectura2,550 palabras

El `InvalidCharError` de las bibliotecas sanitizadoras de nombres de archivo de Python es un error preciso: se dispara cuando una cadena de nombre de archivo contiene un carácter que el sistema operativo de destino prohíbe. Pero la causa casi siempre es la misma: un nombre de archivo llegó desde la entrada del usuario, una subida de archivo o una API externa sin validarse primero. Esta guía explica exactamente qué caracteres desencadenan el error en cada SO, cómo arreglarlo y cómo incorporar la sanitización a tu código para que nunca llegue a producción.

11Caracteres ilegales en Windows< > : " / \ | ? * y más
2Caracteres ilegales en LinuxSolo el byte nulo y la barra inclinada
255Bytes máx. del nombreLímite seguro multiplataforma

¿Qué es FilenameSanitizer?

`FilenameSanitizer` se refiere a bibliotecas de Python — más comúnmente `python-filenamesanitizer` y paquetes similares — que validan y limpian cadenas de nombres de archivo antes de usarlas en operaciones del sistema de archivos. Estas bibliotecas comprueban el nombre propuesto contra las reglas del sistema operativo de destino y devuelven una versión sanitizada o lanzan una excepción cuando un carácter no puede reemplazarse de forma segura.

Por qué es necesaria la sanitización de nombres de archivo

Los nombres de archivo procedentes de fuentes externas — subidas de usuarios, respuestas de API, datos extraídos, registros de bases de datos — contienen frecuentemente caracteres que son perfectamente válidos en el contexto de origen pero ilegales en el sistema de archivos de destino. Un nombre como `report: Q1/2026.pdf` es una etiqueta humana razonable, pero contiene `:` y `/`, ambos ilegales en Windows. Sin sanitización, la llamada `open()` lanza un `OSError` o el archivo se trunca silenciosamente en el carácter ilegal.

Qué significa InvalidCharError

InvalidCharError es la excepción específica que se lanza cuando un nombre de archivo contiene un carácter que la biblioteca no puede reemplazar ni eliminar automáticamente, o cuando la biblioteca está configurada para lanzar en lugar de autocorregir. El mensaje de la excepción incluye el nombre original y el carácter ofensivo, lo que te da todo lo necesario para arreglarlo. Si ves este error sin un traceback claro, pega el stack trace completo en el Explicador de Tracebacks de Python para un desglose en lenguaje claro de la causa raíz.

Note

No todos los errores de nombres de archivo en Python provienen de una biblioteca sanitizadora. Un `ValueError` u `OSError` idéntico puede ser lanzado directamente por `open()`, `os.rename()`, `pathlib.Path()` o `shutil` cuando un nombre sin sanitizar llega a una llamada del sistema de archivos. La solución es la misma sin importar qué llamada lanzó el error: el nombre debe limpiarse antes de alcanzar cualquier operación del sistema de archivos.

¿Qué desencadena InvalidCharError?

El error se dispara cuando la cadena del nombre de archivo contiene uno o más caracteres que el conjunto de reglas del sanitizador marca como ilegales. Los desencadenantes más comunes caen en cuatro categorías, cada una con una vía de solución distinta.

  • Separadores de ruta de Windows - `:` (dos puntos), `\\` (barra invertida), `/` (barra inclinada); aparecen con frecuencia en marcas de tiempo y rutas URL usadas como nombres de archivo
  • Caracteres reservados del shell - `|`, `<`, `>`, `?`, `*`, `"` - comunes en nombres generados a partir de consultas de búsqueda, títulos o nombres de documentos
  • Bytes nulos y caracteres de control - puntos de código Unicode U+0000 a U+001F; a veces inyectados por entradas maliciosas o corrupción de codificación
  • Nombres de dispositivo reservados de Windows - CON, PRN, AUX, NUL, COM1-COM9, LPT1-LPT9 - ilegales como nombres de archivo sin importar la extensión en Windows

El problema de la marca de tiempo

La fuente más común de `InvalidCharError` en aplicaciones reales es un nombre de archivo construido a partir de una marca de tiempo. Una fecha ISO 8601 como `2026-06-11T14:30:00` contiene dos puntos, ilegales en Windows. Cualquier código que genere nombres como `backup_2026-06-11T14:30:00.zip` fallará en Windows pero tendrá éxito silenciosamente en Linux, creando un sutil error multiplataforma. Reemplaza los dos puntos en las marcas de tiempo por guiones o puntos: `2026-06-11T14-30-00`.

El problema de la entrada del usuario

Cuando los usuarios nombran archivos en una interfaz web o suben archivos desde sus dispositivos, los nombres llegan sin ninguna garantía de validez. Un PDF llamado `Invoice: Client/Project Q4.pdf` es un nombre perfectamente natural escrito por un humano que contiene tres caracteres ilegales en Windows. Trata siempre cualquier nombre de archivo que no provenga de tu propio código como entrada no confiable que requiere sanitización antes de usarse.

Warning

Nunca asumas que un nombre de archivo es seguro solo porque sobrevivió en el sistema de origen. Linux permite nombres con `<`, `>`, `*` y `|` — archivos con estos nombres pueden subirse desde una máquina Linux y luego causar `InvalidCharError` cuando tu código orientado a Windows intenta escribirlos. Sanitiza siempre sin importar de dónde venga el nombre.

Caracteres ilegales por sistema operativo

Los tres sistemas operativos principales tienen reglas muy distintas sobre qué caracteres se permiten en los nombres de archivo. Entender las diferencias es esencial para escribir código portátil de manejo de archivos.

CarácterWindowsmacOSLinux
/ (barra inclinada)✗ Ilegal✗ Ilegal✗ Ilegal (sep. de ruta)
\\ (barra invertida)✗ Ilegal✓ Permitido✓ Permitido
: (dos puntos)✗ Ilegal✗ Cuestión heredada✓ Permitido
* ? " < > | (conjunto)✗ Ilegal✓ Permitido✓ Permitido
Byte nulo (\0)✗ Ilegal✗ Ilegal✗ Ilegal
Caracteres de control (0-31)✗ Ilegal✗ Ilegal✗ Ilegal
Punto inicial (.)✓ PermitidoArchivo ocultoArchivo oculto
Punto o espacio final✗ Ilegal✓ Permitido✓ Permitido
Nombres reservados (CON etc.)✗ Ilegal✓ Permitido✓ Permitido

Para código multiplataforma que deba funcionar en los tres sistemas, la regla segura es tratar las reglas de Windows como el mínimo: cualquier carácter ilegal en Windows debe sanitizarse sin importar el SO real en ejecución. Así obtienes nombres de archivo portátiles que funcionan en todas partes. El Sanitizador de Nombres de Archivo para Subidas Multiplataforma valida contra los tres conjuntos de reglas de SO simultáneamente para que puedas comprobar cualquier nombre en una sola pasada.

Cómo arreglar el error

Arreglar un `InvalidCharError` siempre implica el mismo flujo de trabajo: encontrar la fuente del nombre, aplicar la sanitización antes de la llamada al sistema de archivos y verificar el resultado. Sigue estos pasos en orden.

1

Lee el traceback completo para identificar el carácter ofensivo

El mensaje de `InvalidCharError` incluye tanto la cadena original del nombre como el carácter específico rechazado. Copia el traceback completo y anota el carácter. Si es un carácter de control o un byte nulo, puede no ser visible en la salida del error; usa `repr()` sobre la cadena del nombre en tu código para ver la representación escapada e identificar los caracteres ocultos.

2

Localiza de dónde proviene el nombre en tu código

Rastrea el nombre de archivo hasta su fuente usando la pila de llamadas del traceback. Fuentes comunes: el campo `filename` de una subida multipart, una cadena construida a partir de metadatos del usuario, un campo de respuesta de API, una columna de base de datos o un listado externo de archivos. La ubicación de la solución está siempre en la fuente, no en el punto donde se lanza el error.

3

Aplica la sanitización en la frontera de entrada

Añade una pasada de sanitización inmediatamente después de que el nombre entre en tu sistema: en el manejador de subidas, el parser de respuestas de API o dondequiera que los datos externos se conviertan por primera vez en un nombre de archivo. Usa `re.sub(r'[<>:"/\\|?*\x00-\x1F]', '-', name)` como reemplazo base, luego elimina puntos y espacios finales, comprueba contra los nombres reservados de Windows y trunca a 255 bytes. Usa el Validador de Sintaxis Python para comprobar tu función sanitizadora en busca de errores de sintaxis antes de desplegar.

4

Valida el nombre sanitizado antes de la llamada al sistema de archivos

Después de sanitizar, valida el resultado con el Sanitizador de Nombres de Archivo para Subidas Multiplataforma para confirmar que no quedan caracteres ilegales, que el nombre no es un nombre de dispositivo reservado de Windows y que la longitud está dentro del límite de 255 bytes. Esto captura casos límite que la simple sustitución por regex pasa por alto, como un nombre compuesto íntegramente por espacios tras la eliminación, que queda vacío después de recortar.

Sanitizador de Nombres de Archivo para Subidas Multiplataforma

Pega cualquier nombre de archivo y valídalo contra las reglas de Windows, macOS y Linux simultáneamente - identifica caracteres ilegales, nombres reservados, problemas de longitud y proporciona la versión limpia y segura.

Open tool

Sanitizar nombres de archivo manualmente en Python

Si prefieres no depender de una biblioteca de terceros, puedes implementar un sanitizador de nombres de archivo robusto en Python puro. El enfoque cubre todas las restricciones de Windows y multiplataforma sin dependencias externas.

La lógica central de sanitización

Un sanitizador de nombres de archivo completo en Python necesita cinco operaciones aplicadas en secuencia: normalizar Unicode a forma compuesta (NFC) para que caracteres como las letras con tilde se almacenen como puntos de código únicos; reemplazar todos los caracteres ilegales de Windows y los caracteres de control ASCII por un sustituto seguro; recortar puntos, espacios y guiones iniciales y finales, problemáticos en Windows; comprobar contra la lista de nombres de dispositivo reservados de Windows y añadir un sufijo si coincide; y finalmente truncar a 255 bytes al codificar como UTF-8.

Manejar nombres de archivo Unicode

Las aplicaciones modernas manejan rutinariamente nombres de archivo con caracteres no ASCII — árabe, chino, japonés, caracteres latinos con tilde. Todos son legales en los sistemas de archivos modernos (NTFS, APFS, ext4) pero pueden causar problemas cuando ocurren conversiones de codificación. Un nombre válido en UTF-8 puede corromperse si el sistema de archivos o el SO están configurados para una codificación heredada como Latin-1 o Windows-1252. Si encuentras nombres con caracteres confusos, pásalos por la Herramienta de Reparación Unicode y de Codificación para identificar y corregir el problema de codificación antes de la sanitización.


Cuándo lanzar y cuándo autocorregir

Tienes dos opciones cuando se encuentra un carácter ilegal: lanzar una excepción (el comportamiento predeterminado de la biblioteca `python-filenamesanitizer`) o autorreemplazar con un carácter seguro. Para los manejadores de subidas, el autorreemplazo suele ser la elección correcta: limpiar silenciosamente `invoice: Q1.pdf` a `invoice- Q1.pdf` es mejor que hacer fallar la subida. Para código interno que genera sus propios nombres, lanzar es mejor: un `InvalidCharError` en tu propio código es un error que corregir, no un caso límite que manejar en silencio.

Tip

Al autorreemplazar caracteres, prefiere el guion (`-`) sobre el guion bajo como carácter de reemplazo. Los guiones son más legibles que los guiones bajos en nombres de varias palabras y están universalmente permitidos en todos los sistemas operativos. Evita reemplazar con un espacio: aunque los espacios son legales en nombres de archivo en todos los SO modernos, causan problemas en comandos de shell y algunas herramientas heredadas.

Buenas prácticas multiplataforma para nombres de archivo

La estrategia de sanitización más fiable es un conjunto de reglas consistentes aplicadas en cada frontera de entrada, en lugar de una serie de correcciones ad hoc que crecen con el tiempo. Estas prácticas evitan que `InvalidCharError` y sus parientes aparezcan en primer lugar.

Construye nombres de archivo a partir de componentes seguros

Siempre que sea posible, genera nombres de archivo a partir de entradas controladas en lugar de pasar cadenas proporcionadas por el usuario directamente. Construye nombres a partir de identificadores sanitizados, UUID o marcas de tiempo con los dos puntos reemplazados: un UUID como `550e8400-e29b-41d4-a716-446655440000` ya es seguro en todas las plataformas. Si se requiere un nombre legible por humanos, sanitízalo primero y luego añade el identificador seguro como sufijo para garantizar la unicidad.

Valida en cada frontera de SO

  • Subidas de archivos - sanitiza el nombre subido antes de guardar, incluso si tu framework web proporciona un campo de nombre de archivo
  • Respuestas de API - trata cualquier campo de nombre de archivo de una API externa como no confiable; valida antes de usar
  • Registros de base de datos - los nombres almacenados en una base de datos pueden haberse guardado antes de que tus reglas de sanitización existieran
  • Archivos de configuración - los nombres leídos de archivos de configuración pueden ser incorrectos si la configuración fue editada por un usuario
  • Argumentos de línea de comandos - los argumentos de ruta proporcionados por el usuario pueden contener expansiones de shell o caracteres especiales

Prueba en todas las plataformas objetivo

Un error de nombre de archivo que solo se manifiesta en Windows es invisible en un entorno de desarrollo exclusivamente Linux. Si tu aplicación se ejecutará en Windows, prueba tu código de manejo de archivos en Windows, o añade un trabajo de CI que se ejecute en un runner de Windows. El Sanitizador de Nombres de Archivo para Subidas Multiplataforma proporciona una comprobación agnóstica del SO que puedes ejecutar desde cualquier plataforma, convirtiéndolo en un sustituto práctico de las pruebas multi-SO durante el desarrollo.

Warning

No uses `os.path.basename()` solo como medida de seguridad para nombres de archivo subidos. Elimina componentes de ruta pero no sanitiza caracteres ilegales. Un nombre como `../../../etc/passwd` se convierte en `passwd` tras `os.path.basename()` — un intento de path traversal — pero `invoice:Q1.pdf` permanece como `invoice:Q1.pdf` sin cambios. Aplica siempre la prevención de path traversal y la sanitización de caracteres como pasos separados.

Validar nombres de archivo antes de usarlos

Un sanitizador que autorreemplaza caracteres es una salvaguarda de producción. Un validador que comprueba y reporta problemas es una herramienta de desarrollo y depuración. Ambos tienen su lugar, y usarlos juntos te da la cobertura más fuerte.

Qué comprueba la herramienta Filename Sanitizer

El Sanitizador de Nombres de Archivo para Subidas Multiplataforma valida nombres de archivo contra los tres conjuntos de reglas de SO principales en una pasada. Comprueba caracteres ilegales (Windows, macOS, Linux), nombres de dispositivo reservados de Windows, puntos y espacios finales (ilegales en Windows), puntos iniciales (señal de archivo oculto en Unix), bytes nulos y caracteres de control, y la longitud del nombre tanto en caracteres como en bytes UTF-8. También te muestra la versión segura sanitizada del nombre junto con el informe de validación.

Integrar la validación en CI

Para aplicaciones que generan nombres de archivo a partir de plantillas o patrones configurables, añade una prueba unitaria que valide los nombres generados contra las reglas multiplataforma en cada compilación. Una plantilla de nombre que funciona en tu entorno actual puede producir un `InvalidCharError` tras un cambio de configuración que introduzca dos puntos en el patrón. Detectarlo en CI es significativamente menos costoso que depurarlo en producción.

Key takeaways

  • `InvalidCharError` se dispara cuando un nombre de archivo contiene un carácter ilegal en el SO de destino: el mensaje de error siempre identifica el carácter específico.
  • Windows prohíbe `< > : " / \ | ? *`, los caracteres de control, los puntos/espacios finales y los nombres reservados (CON, NUL, COM1-9, LPT1-9).
  • Linux solo prohíbe los bytes nulos y las barras inclinadas, pero el código portátil debe aplicar las reglas de Windows universalmente.
  • Sanitiza siempre los nombres de archivo en la frontera de entrada (manejador de subidas, parser de API) en lugar de capturar excepciones después del hecho.
  • Usa el Sanitizador de Nombres de Archivo para Subidas Multiplataforma para validar cualquier nombre contra los tres conjuntos de reglas de SO en una pasada.
  • Los nombres de archivo Unicode con corrupción de codificación necesitan la Herramienta de Reparación Unicode y de Codificación antes de la sanitización.
  • Autorreemplaza los caracteres ilegales por guiones en los manejadores de subidas; lanza excepciones en el código interno donde los nombres inválidos son un error que corregir.

Preguntas frecuentes

InvalidCharError is an exception raised by the `python-filenamesanitizer` library (and similar filename validation libraries) when a filename string contains one or more characters that are illegal on the target operating system. The error identifies the specific character that caused the rejection. It is most commonly encountered when handling filenames from user uploads, API responses, or external data sources that have not been validated before being passed to filesystem operations.

Windows forbids the following characters in filenames: `< > : " / \ | ? *` and all control characters (Unicode codepoints U+0000 through U+001F). Windows also reserves specific names for system devices: CON, PRN, AUX, NUL, COM1-COM9, and LPT1-LPT9 - these names cannot be used as filenames regardless of extension. Additionally, filenames cannot end with a dot (.) or a space. These rules apply to all Windows filesystems including NTFS and FAT32.

macOS and Linux (POSIX) filesystems are significantly more permissive. The only universally forbidden characters are the null byte (\0) and the forward slash (/). However, filenames beginning with a dot (.) are treated as hidden files, filenames beginning with a hyphen can interfere with command-line argument parsing, and spaces and special shell characters (`, $, !, &, ;, |, and others) create problems in shell scripts even if the OS allows them. For portable code, treat all Windows-illegal characters as off-limits.

You can sanitize filenames with a regular expression and a few string operations. Replace all Windows-illegal characters (`< > : " / \ | ? *`) and control characters with a hyphen or underscore. Strip leading and trailing dots and spaces. Check the result against the Windows reserved name list (CON, PRN, AUX, NUL, COM1-9, LPT1-9) and append a suffix if it matches. Truncate to 255 bytes for NTFS compatibility. This covers the vast majority of cases without requiring a third-party library.

In Django, the recommended approach is to override the `generate_filename()` method on your storage backend or use Django's built-in `get_valid_name()` utility from `django.utils.text`. This function strips characters that are not alphanumeric, dots, underscores, or hyphens. For uploads that may contain Unicode names or non-ASCII characters from international users, run the name through `unicodedata.normalize("NFC", name)` first to normalize composed forms, then apply the sanitizer.

Yes - if the exception is unhandled, the file write operation failed and no file was created on disk. The exception is raised before any data is written. You need to catch the exception, sanitize the filename, and retry the write with the clean name. In a web application, this means wrapping the filename sanitization in a try/except block in your upload handler, applying a fallback sanitizer when the error is caught, and logging the original filename for debugging.

The safest approach is proactive validation before attempting any filesystem operation. Pass the filename through the Filename Sanitizer for Cross-Platform Uploads tool to identify issues during development, and implement a programmatic check in your code using a validation function that tests against all three OS rule sets simultaneously. This is more reliable than catching exceptions after the fact, because some invalid filenames cause silent errors or incorrect behaviour rather than explicit exceptions.

The limit depends on the filesystem. NTFS (Windows) allows 255 UTF-16 code units for the filename component, excluding the path. Most Linux filesystems (ext4, XFS) allow 255 bytes in the filename component. macOS (APFS, HFS+) allows 255 UTF-16 code units. The safe cross-platform limit is 255 bytes. When filenames contain non-ASCII Unicode characters (which encode to 2-4 bytes each in UTF-8), a filename that appears short in characters can exceed 255 bytes - always measure in encoded bytes when enforcing the limit.

ShareXLinkedIn