You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatsby在onCreateNode中批量用外部URL创建File节点报EPERM错误如何解决

问题根因

你代码里存在两个核心问题导致报错:

  1. 多余的id取值逻辑:你在遍历URL数组调用createRemoteFileNode时,已经直接返回了文件节点的id值,Promise.all返回的responses数组内存储的就是字符串类型的id,后续再执行d.id会得到undefined,导致字段存储异常。
  2. 并发请求临时文件冲突:Windows系统下并发调用createRemoteFileNode时,如果没有显式指定唯一的name参数,Gatsby自动生成的临时文件名可能出现冲突,触发EPERM权限错误。

修正后的代码

exports.onCreateNode = async ({
  node,
  actions: { createNode, createNodeField },
  createNodeId,
  cache,
  store,
}) => {
  if (node.internal.type === 'MyType') {
    // 处理单URL字段
    const fileNodeImageMap = await createRemoteFileNode({
      url: node.imageLink,
      parentNodeId: node.id,
      createNode,
      createNodeId,
      cache,
      store,
    });

    if (fileNodeImageMap) {
      createNodeField({ node, name: 'imageLinkFile', value: fileNodeImageMap.id });
    }

    // 处理多URL数组字段
    if (node.additionalImageLink) {
      // split后加trim清除URL前后多余空格,避免请求失败
      const links = node.additionalImageLink.split(',').map(url => url.trim());
      const additionalImages = links.map(async (url, index) => {
        const fileNodeImage = await createRemoteFileNode({
          url: url,
          parentNodeId: node.id,
          createNode,
          createNodeId,
          cache,
          store,
          // 显式指定唯一name,避免并发请求的临时文件名冲突
          name: `${node.id}-additional-img-${index}`
        });
        return fileNodeImage?.id;
      });

      const responses = await Promise.all(additionalImages);
      // 过滤掉请求失败产生的空值
      const validIds = responses.filter(Boolean);
      if (validIds.length) {
        createNodeField({ node, name: 'additionalImageLinkFile', value: validIds });
      }
    }
  }
};

验证步骤

修改代码后执行以下命令重启服务即可:

  • gatsby clean
  • gatsby develop

内容的提问来源于stack exchange,提问作者lezan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:57:04