Figma plugin development: Function wrapping error

Hey everyone! I’m working on a Figma plugin and I’ve hit a snag. When I try to upload an image, I get this weird error: Uncaught Error: Cannot wrap function. It pops up after I send the file data through postMessage.

My plugin is pretty simple right now. It’s just supposed to let you pick an image and then log the file data to the console when you click upload. But it’s not working as expected.

Here’s a quick example of what I’m trying to do:

<body>
  <h1>Picture Uploader</h1>
  <input type="file" id="picInput" accept="image/*" multiple>
  <button id="sendPic">Send</button>
  <script>
    document.getElementById('sendPic').onclick = () => {
      const input = document.getElementById('picInput');
      const pics = input.files;
      parent.postMessage({ pluginMessage: { type: 'send-pictures', pics } }, '*');
    };
  </script>
</body>

And in the main code:

figma.showUI(__html__);

figma.ui.onmessage = async (msg) => {
    if (msg.type === 'send-pictures') {
        const pics = msg.pics;
        console.log('Sent pictures:', pics);
    }
    figma.closePlugin();
};

Any ideas what might be causing this error? I’m pretty new to Figma plugin development, so I might be missing something obvious. Thanks in advance for any help!

I encountered a similar issue when developing my first Figma plugin. The problem lies in trying to pass the File object directly through postMessage. JavaScript can’t serialize complex objects like File, which is why you’re getting that error.

Here’s a workaround I found effective:

Instead of sending the entire File object, extract the necessary information and send that. For instance, you could create an array of objects containing the file name and size for each selected file.

In your HTML file, modify the script like this:

document.getElementById('sendPic').onclick = () => {
  const input = document.getElementById('picInput');
  const pics = Array.from(input.files).map(file => ({
    name: file.name,
    size: file.size
  }));
  parent.postMessage({ pluginMessage: { type: 'send-pictures', pics } }, '*');
};

This approach should resolve the wrapping error. You can then handle this data in your main code and proceed with file operations as needed. Remember to adjust your TypeScript code accordingly to match the new data structure.

The issue you’re facing is a common pitfall in Figma plugin development. File objects can’t be directly serialized and sent through postMessage. To resolve this, you need to convert the file data into a format that can be safely transmitted.

Here’s a solution that worked for me:

Instead of sending the entire File object, use FileReader to convert each image to a data URL. This way, you can send the image data as a string.

Modify your HTML script like this:

document.getElementById('sendPic').onclick = () => {
  const input = document.getElementById('picInput');
  const files = input.files;
  const readers = [];

  for (let i = 0; i < files.length; i++) {
    const reader = new FileReader();
    readers.push(new Promise((resolve) => {
      reader.onload = (e) => resolve(e.target.result);
      reader.readAsDataURL(files[i]);
    }));
  }

  Promise.all(readers).then((results) => {
    parent.postMessage({ pluginMessage: { type: 'send-pictures', pics: results } }, '*');
  });
};

This approach converts your images to data URLs, which can be safely transmitted and used in your main plugin code. Remember to adjust your TypeScript code to handle these data URLs instead of File objects.