Search code examples
node.jsstrapi

Strapi >>> Facing "ENAMETOOLONG: name too long" error


System information

  • Strapi Version: 4.1.12
  • Operating System: MacOS
  • Database: Postgres
  • Node Version: 16.15.1
  • NPM Version: 8.11.0
  • Yarn Version: 1.22.11

When I try to upload a file with long name then I’m getting below error:

error: ENAMETOOLONG: name too long

File name: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book here a.pdf

Can someone help me with the root cause of this error?


Solution

  • It's your file system. Your example filename looks exactly 255 bytes, but you have a "fancy quote" in there. It's not an apostrophe (0x27) or backtick (0x60) but three bytes, 0x2e 0x80 0x99. The error is entirely correct: name too long.

    You can check this list, search for character U+2019 and you'll see this sequence of bytes matches your quote character.


    JavaScript's string functions, such as ''.substr() work on characters and not bytes, so simply using filename.substr(0, 255) will not work.

    The best way is to use an external package that knows how to trim UTF-8 strings without breaking special character sequences, like your multi-byte quote or emoji.

    const truncate = require('truncate-utf8-bytes');
    const { extname, basename } = require('path');
    
    function trimFilenameToBytes(filename, maxBytes = 255) {
      // By extracting the file extension from the filename,
      // it'll trim "verylong.pdf" to "verylo.pdf" and not "verylong.p"
      const ext = extname(filename);
      const base = basename(filename, ext);
      const length = Buffer.byteLength(ext);
      const shorter = truncate(base, Math.max(0, maxBytes - length)) + ext;
      // Just in case the file extension's length is more than maxBytes.
      return truncate(shorter, maxBytes);
    }
    
    const filename = 'Lorem Ipsum is simply dummy \
    text of the printing and typesetting industry. Lorem Ipsum has \
    been the industry’s standard dummy text ever since the 1500s, \
    when an unknown printer took a galley of type and scrambled it \
    to make a type specimen book here a.pdf';
    
    console.log(
      'This string is',
      filename.length,
      'characters and',
      Buffer.byteLength(filename, 'utf-8'),
      'bytes'
    );
    
    console.log(trimFilenameToBytes(filename));
    
    // Will log the following, note how it's 2 bytes shorter:
    // This string is 255 characters and 257 bytes
    // Lorem Ipsum is simply dummy \
    // text of the printing and typesetting industry. Lorem Ipsum has \
    // been the industry’s standard dummy text ever since the 1500s, \
    // when an unknown printer took a galley of type and scrambled it \
    // to make a type specimen book here.pdf