Figma Plugin throws symbol unwrap error when extracting fonts from text with multiple styles

I’m working on a Figma plugin and running into an issue when trying to extract font information from text elements that have mixed formatting. Whenever I select a text node with different font styles applied to different parts, my plugin crashes with this error message:

figma_app.min.js.br:5 Error: in postMessage: Cannot unwrap symbol at (PLUGIN_477_SOURCE:26)

Here’s my selection handler code:

figma.on("selectionchange", () => {
  const currentSelection = figma.currentPage.selection;

  if (currentSelection && currentSelection.length > 0) {
    const extractedFonts = extractFontsFromNodes(currentSelection);
    figma.ui.postMessage({ type: "fontData", fonts: extractedFonts });
  } else {
    figma.ui.postMessage({ type: "emptySelection" });
  }
});

And here’s the function that processes the fonts:

function extractFontsFromNodes(nodes: ReadonlyArray<SceneNode>) {
  const fontCollection = new Map();

  function analyzeNode(element: SceneNode) {
    if (element.type === "TEXT") {
      const typeface = element.fontName as FontName;
      const familyName = typeface ? typeface.family : "";
      const styleName = typeface ? typeface.style : "";
      const weightValue = element.fontWeight || "";

      if (!fontCollection.has(familyName)) {
        fontCollection.set(familyName, new Set());
      }

      const styleCollection = fontCollection.get(familyName);
      styleCollection.add({ style: styleName, weight: weightValue });
    } else if (element.type === "GROUP" || element.type === "FRAME") {
      for (const child of (element as GroupNode | FrameNode).children) {
        analyzeNode(child);
      }
    }
  }

  for (const element of nodes) {
    analyzeNode(element);
  }

  const result = [];

  for (const [family, styles] of fontCollection) {
    result.push({ family: family, styles: Array.from(styles) });
  }

  return result;
}

The error only happens with text that has mixed styles. Regular text works fine. How can I handle this situation properly?

I encountered this exact same problem a few months ago. The symbol unwrap error occurs because you’re trying to access font properties directly on mixed-style text nodes, but Figma can’t serialize the complex font data structure properly when posting to the UI.

The core issue is in your postMessage call - you’re attempting to send font objects that contain non-serializable data. I found that converting everything to plain strings before sending resolves this completely.

Try modifying your font collection to store only primitive values:

const styleInfo = {
style: styleName.toString(),
weight: weightValue.toString()
};
styleCollection.add(JSON.stringify(styleInfo));

Then when building your result array, parse it back. This approach eliminates the symbol references that cause the unwrap error. Also make sure to handle cases where fontName might be mixed by checking if it’s a symbol before accessing properties. The error disappears once you ensure all data being passed through postMessage consists only of serializable primitives.

had this same bug last week! the problem is mixed text nodes have fontName as a symbol instead of object. quick fix - check if its mixed first with element.fontName === figma.mixed then use getRangeFontName() like grace mentioned. also wrap your postMessage in try-catch to avoid crashes

The issue you’re encountering is due to text nodes with mixed formatting, which result in multiple font properties over different character ranges. Instead of trying to access element.fontName, you should iterate through the text segments. Modify your text handling logic as follows:

if (element.type === "TEXT") {
  const textLength = element.characters.length;
  
  for (let i = 0; i < textLength; i++) {
    const fontAtPosition = element.getRangeFontName(i, i + 1) as FontName;
    const familyName = fontAtPosition.family;
    const styleName = fontAtPosition.style;
    
    if (!fontCollection.has(familyName)) {
      fontCollection.set(familyName, new Set());
    }
    
    const styleCollection = fontCollection.get(familyName);
    styleCollection.add({ style: styleName, weight: "" });
  }
}

This way, you can gather the font information for each character individually, which will resolve the unwrap error.

The unwrap error stems from attempting to access fontWeight property on mixed-style text nodes, which isn’t directly available. When text has multiple formatting styles, properties like fontWeight become undefined or return symbols that can’t be serialized.

I solved this by removing the fontWeight access entirely and using getRangeFontSize() and getRangeFontName() methods instead. Your current code tries to read element.fontWeight which doesn’t exist on mixed text nodes. Replace that line with proper range-based queries.

Also, Sets containing objects won’t work properly for deduplication since object references differ. Convert your style objects to strings when adding to the Set, or use a different approach for tracking unique font combinations. The combination of accessing non-existent properties and trying to serialize complex nested objects through postMessage is what triggers the symbol unwrap error.