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

IFC转SVF翻译失败:Extractor返回-1073741829错误求助

问题:IFC文件上传Autodesk Forge成功但转SVF失败,返回TranslationWorker-InternalFailure

我通过分块方式将IFC文件上传至Autodesk Forge,上传流程返回成功,但调用模型转换接口后,通过manifest接口查询到如下错误:

{
    "urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bnY5a2cyZnB5bTFsdDQ5MDkxdzdobXVsbzlha3RldXdfdHV0b3JpYWxfYnVja2V0L2MyMWE2MzcwZTMwNzJmM2IwZTA3OWE5MzRjYWM4YTZlLmlmYw",
    "derivatives": [
        {
            "hasThumbnail": "false",
            "name": "c21a6370e3072f3b0e079a934cac8a6e.ifc",
            "progress": "complete",
            "messages": [
                {
                    "type": "error",
                    "message": "Unrecoverable exit code from extractor: -1073741829",
                    "code": "TranslationWorker-InternalFailure"
                }
            ],
            "outputType": "svf",
            "status": "failed"
        }
    ],
    "hasThumbnail": "false",
    "progress": "complete",
    "type": "manifest",
    "region": "US",
    "version": "1.0",
    "status": "failed"
}

转换代码如下:

public async convertFileToSvfFormat(forgeApiAccessToken: string, urn: string): Promise<any> {
    const forgeFileConversionResponse = await firstValueFrom(
        this.forgeHttpService.post(
            `modelderivative/v2/designdata/job`,
            JSON.stringify({
                input: {
                    urn,
                },
                output: {
                    formats: [
                        {
                            type: this.DEFAULT_FORGE_FORMAT_TYPE, // 'svf'
                            views: this.DEFAULT_FORGE_FORMAT_VIEWS, // ["2d", "3d"]
                        },
                    ],
                },
            }),

            {
                headers: {
                    "Authorization": `Bearer ${forgeApiAccessToken}`,
                    "Content-Type": "application/json",
                },
            },
        ),
    )

    return forgeFileConversionResponse
}

分块上传代码如下:

public async uploadFileToForgeBucket(forgeApiAccessToken: string, file: Express.Multer.File): Promise<void> {
    // When de-hardcoding the Forge acocunt to assign accounts to each user, de-hardcode this value here
    const bucketKey = this.getBucketKey(this.hardcodedForgeClientId)

    const path = join(__dirname, "../../../../upload/") + file.filename

    const parts = Math.floor(this.calculateFileChuncks(path))

    const signedUrls = await this.getS3SignedUrl(forgeApiAccessToken, file.filename, parts)

    parts > 1 && splitFileInChunks(path, parts)

    console.log(`Number of parts: ${parts}`)

    const timerId = setTimeout(async () => {
        const fileName = parts > 1 ? `${file.filename}.sf-part${parts}` : file.filename
        const exists = existsSync(`./upload/${fileName}`)
        console.log(exists && "Last chunk exists and read...")
        if (exists) {
            console.log("Starting upload...")
            for (let i = 0; i < signedUrls.urls.length; i++) {
                const currentUrl = signedUrls.urls[i]
                let part: string
                if (parts > 9) {
                    part = (i + 1).toString().length === 1 ? `0${i + 1}` : (i + 1).toString()
                } else {
                    part = (i + 1).toString()
                }
                const fileName = parts > 1 ? path + `.sf-part${part}` : path

                const stream = readFileSync(fileName)

                await firstValueFrom(
                    this.forgeHttpService.put(
                        currentUrl,
                        { data: stream },
                        {
                            headers: {
                                "Content-Type": "application/octet-stream",
                                "Content-Length": stream.length,
                                // "Content-Range": `bytes 0-${stream.length}`,
                                "Content-Disposition": `${file.filename}.sf-part${part}`,
                            },
                        },
                    ),
                )
                const percentage = ((i + 1) / parts) * 100
                console.log(`Uploading file... ${percentage.toFixed(2)}%`)
            }
            console.log("Upload complete. Processing...")
            console.log("Re-unifying file:", `${file.filename}`)
            const result = await firstValueFrom(
                this.forgeHttpService.post(
                    `https://developer.api.autodesk.com/oss/v2/buckets/${bucketKey}/objects/${file.filename}/signeds3upload`,

                    {
                        uploadKey: signedUrls.uploadKey,
                    },
                    {
                        headers: {
                            "Authorization": `Bearer ${forgeApiAccessToken}`,
                            "Content-Type": "application/json",
                        },
                    },
                ),
            )
            clearInterval(timerId)
            console.log(result.data)
            const toBase64 = stringToBase64(result.data.objectId)
            console.log(toBase64)
            const translation = await this.convertFileToSvfFormat(forgeApiAccessToken, toBase64)
            console.log(translation)
            // console.log(translation, "trans")
        }
    }, 2000)
}

上传返回成功:

data: {
    result: 'success',
    urn: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6eG02ZjIxbWUxMHNxbTc4NmlhY3c2cTV6bjUxeWdpZmhfdHV0b3JpYWxfYnVja2V0L3JhY19iYXNpY19zYW1wbGVfcHJvamVjdF92My5pZmM',
    acceptedJobs: { output: [Object] }
  }

请问遗漏了什么?该如何定位错误原因?


分析与解决方案

错误代码核心含义

-1073741829对应Windows系统的0xC0000005错误(访问违规),说明Forge的IFC提取器在读取文件时遇到无效数据导致崩溃,本质原因大概率是上传后的文件损坏,或原IFC文件本身存在格式/兼容性问题。

排查步骤

1. 验证原IFC文件的有效性

直接将本地原IFC文件拖到Autodesk Viewer在线工具中,检查是否能正常加载显示:

  • 如果无法加载,说明原文件本身存在格式错误或不兼容问题(比如使用了Forge不支持的IFC版本、文件损坏),需要修复原文件后再尝试上传转换。
  • 如果能正常加载,说明问题出在上传环节。

2. 验证上传后文件的完整性

调用Forge OSS接口下载上传后的文件,计算其MD5哈希值,与本地原文件的MD5对比:

  • 若哈希值不一致,说明分块上传过程中文件损坏,重点排查上传代码的以下问题:
    • 分块命名逻辑不统一:检查splitFileInChunks生成的分块文件名(比如是.sf-part1还是.sf-part01),是否与上传代码中拼接的文件名完全一致。代码中当parts>9时会给分块编号补0,但如果splitFileInChunks生成的分块没有补0,就会导致读取错误的块内容。
    • 异步操作依赖延迟不可靠:代码中用setTimeout延迟2秒再上传,若分块拆分耗时超过2秒,会导致上传时部分块尚未生成完成,最终合并的文件不完整。应改为等待splitFileInChunks执行完成后再启动上传(如果splitFileInChunks是异步函数,需用await;同步函数则直接去掉延迟)。
    • 冗余请求头干扰:上传分块时无需设置Content-Disposition头,该头可能干扰Forge的块合并逻辑,建议移除。
    • 未验证分块上传结果:每个分块上传后,应检查响应状态码是否为200 OK,确保所有块都上传成功。

3. 排查转换请求的细节

  • 确认转换请求中的urn是正确的Base64编码(不含URL特殊字符),代码中stringToBase64函数需确保是标准的Base64编码,且对objectId进行了正确的URL安全处理(替换+为-,/为_,去掉末尾的=)。
  • 尝试只转换3D视图(views: ["3d"]),排除2D视图转换的兼容性问题。

4. 极端情况排查

如果以上步骤都没问题,可能是Forge的IFC提取器对某些特定IFC结构不兼容:

  • 用一个已知正常的IFC文件(比如Autodesk官方提供的示例IFC)重复上传转换流程,验证是否能成功。
  • 若示例文件能成功转换,说明原文件存在特殊结构导致兼容问题,可联系Forge技术支持提交文件进一步排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:15:32