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

Node.js 18读取S3 JSON文件时触发TypeError: Converting circular structure to JSON错误

Node.js 18 使用 @aws-sdk/client-s3 读取S3 JSON文件时出现循环引用序列化错误

错误详情

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'TLSSocket'
| property 'parser' -> object with constructor 'HTTPParser'
--- property 'socket' closes the circle
at JSON.stringify (<anonymous>)
at responseHook (/opt/wrapper.js:147:24)
at /opt/nodejs/node_modules/@opentelemetry/instrumentation-aws-sdk/build/src/aws-sdk.js:149:61
at safeExecuteInTheMiddle (/opt/nodejs/node_modules/@opentelemetry/instrumentation/build/src/utils.js:28:18)
at AwsInstrumentation._callUserResponseHook (/opt/nodejs/node_modules/@opentelemetry/instrumentation-aws-sdk/build/src/aws-sdk.js:149:54)
at /opt/nodejs/node_modules/@opentelemetry/instrumentation-aws-sdk/build/src/aws-sdk.js:269:34
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

场景与代码片段

在Node.js 18环境下,使用@aws-sdk/client-s3的S3Client和GetObjectCommand读取S3中的JSON文件,调用.transformToString('utf-8')将返回内容转为字符串时触发了上述错误,相关代码如下:

const client = new S3Client({
    region
});
const params = {
    Bucket: bucket,
    Key: key
};
const response = await client.send(new GetObjectCommand(params));
const body = await response.Body.transformToString('utf-8');

解决方案

这个错误和transformToString本身无关,是OpenTelemetry的AWS SDK instrumentation插件在序列化响应对象时,试图处理包含循环引用的TLSSocket等底层网络对象导致的。可通过以下方式解决:

  • 禁用OpenTelemetry对AWS SDK的自动 instrumentation
    如果不需要追踪AWS SDK调用,可直接在代码中关闭该插件,或在部署配置中移除相关依赖。示例代码:

    const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
    const { registerInstrumentations } = require('@opentelemetry/instrumentation');
    const { AwsInstrumentation } = require('@opentelemetry/instrumentation-aws-sdk');
    
    registerInstrumentations({
        instrumentations: [
            // 移除或注释掉AWS SDK instrumentation的初始化代码
            // new AwsInstrumentation(),
        ],
    });
    
  • 修改responseHook逻辑,避免序列化整个响应对象
    如果必须保留追踪,需调整/opt/wrapper.js第147行的responseHook实现,只序列化业务所需字段(比如响应体内容),不要直接序列化包含底层网络连接的完整response对象。

  • 临时替换响应体读取方式
    可以绕开transformToString,改用流读取方式临时规避错误:

    const { Readable } = require('stream');
    const response = await client.send(new GetObjectCommand(params));
    const body = await new Promise((resolve, reject) => {
        const chunks = [];
        Readable.from(response.Body)
            .on('data', chunk => chunks.push(chunk))
            .on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))
            .on('error', reject);
    });
    

内容的提问来源于stack exchange,提问作者shakya-abhi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:24