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

MASV门户文件上传自动化失败:包最终化时报错需至少含1个文件

问题:MASV API包最终化时返回package must have at least 1 file错误

我通过MASV门户向LucidLink文件空间动态上传文件,严格遵循MASV API上传文档执行操作,各步骤看似正常,但在最后一步包最终化时收到400错误,错误信息为package must have at least 1 file。

我的Node.js实现代码

const axios = require("axios");
const fs = require("fs");
const convert = require("xml-js");

(async () => {
  try {
    const { data: token_data } = await axios.post(
      `https://api.massive.app/v1/portals/${portalId}/packages`,
      {
        sender: SENDER_EMAIL,
        name: PACKAGE_NAME,
        description: "",
      },
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    );
    const portal_access_token = token_data.access_token;
    const package_id = token_data.id;

    const packageHeaders = {
      "Content-Type": "application/json",
      "X-Package-Token": portal_access_token,
    };

    const { data: fileToPkg } = await axios.post(
      `https://api.massive.app/v1/packages/${package_id}/files`,
      {
        kind: "file",
        name: "Person.png",
        path: "./",
        last_modified: "2023-07-25T10:59:00.000Z",
      },
      {
        headers: packageHeaders,
      }
    );

    const bluePrint = fileToPkg.create_blueprint;
    const bluePrintUrl = bluePrint.url;
    const bluePrintHeaders = bluePrint.headers;
    const bluePrintMethod = bluePrint.method;
    const fileId = fileToPkg.file.id;

    const { data: bluePrintData } = await axios.post(bluePrintUrl, null, {
      headers: bluePrintHeaders,
    });

    let result = convert.xml2json(bluePrintData, {
      compact: true,
      spaces: 4,
    });
    let jsonResult = JSON.parse(result);

    // Obtain upload urls
    const uploadId = jsonResult?.InitiateMultipartUploadResult?.UploadId._text;

    const { data: uploadUrls } = await axios.post(
      `https://api.massive.app/v1/packages/${package_id}/files/${fileId}?start=0&count=1`,
      { upload_id: uploadId },
      { headers: packageHeaders }
    );

    const { url, method } = uploadUrls[0];
    const FILE_PATH = "Person.png";

    axios({
      method,
      url,
      data: fs.readFileSync(FILE_PATH),
    })
      .then((response) => {
        axios({
          method: "POST",
          url: `https://api.massive.app/v1/packages/${package_id}/files/${fileId}/finalize`,
          headers: packageHeaders,
          data: {
            size: fs.statSync(FILE_PATH).size,
            file_extras: { upload_id: uploadId },
            chunk_extras: [
              {
                partNumber: "1",
                etag: response.headers.etag,
              },
            ],
          },
        })
          .then((response) => {
            console.log("response", response.status);
          })
          .catch((error) => console.error(error.message));
      })
      .catch((error) => {
        console.log(error.message, error.response.data);
      });

    const { data: packageFinalData } = await axios.post(
      `https://api.massive.app/v1/packages/${package_id}/finalize`,
      {},
      {
        headers: packageHeaders,
      }
    );

  } catch (error) {
    console.log("error", error.message, error.response?.data);
  }
})();

错误定位

错误明确出现在最后一个axios请求:

const { data: packageFinalData } = await axios.post(
      `https://api.massive.app/v1/packages/${package_id}/finalize`,
      {},
      {
        headers: packageHeaders,
      }
    );

问题原因

文件上传和文件finalize操作是通过.then()链式调用的异步任务,而包finalize的await请求并未等待这些异步任务完成就直接执行。此时MASV服务器还未收到文件上传完成的确认,因此判定包内无文件,返回错误。

解决方法

将文件上传和文件finalize的异步操作改为await,确保这些步骤全部完成后再执行包finalize,同时避免回调地狱:

// 替换原有的.then()链式调用部分
const uploadResponse = await axios({
  method,
  url,
  data: fs.readFileSync(FILE_PATH),
});

await axios({
  method: "POST",
  url: `https://api.massive.app/v1/packages/${package_id}/files/${fileId}/finalize`,
  headers: packageHeaders,
  data: {
    size: fs.statSync(FILE_PATH).size,
    file_extras: { upload_id: uploadId },
    chunk_extras: [
      {
        partNumber: "1",
        etag: uploadResponse.headers.etag,
      },
    ],
  },
});

console.log("文件已完成上传并finalize");

// 现在再执行包finalize
const { data: packageFinalData } = await axios.post(
  `https://api.massive.app/v1/packages/${package_id}/finalize`,
  {},
  {
    headers: packageHeaders,
  }
);

这样就能保证文件完全上传并完成finalize后,再去finalize整个包,服务器就能识别到包内的文件了。

内容的提问来源于stack exchange,提问作者Ifeanyi Desmond Dike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:27:04