ES /docs

MeshService::run | error: {"stack":"Error: forge_bimmodel_extractor failed to extract mesh, process(

RCA: MeshService::run | forge_bimmodel_extractor failed to extract mesh

Overview#

What Happened#

2026-06-24 16:00:16 KST 에 production us-west-2 region 의 cupixworks-any-mesh-agent 가 BIM id 20141 의 mesh 추출 작업을 처리하던 중 native addon @cupix-compute/forge_bimmodel_extractor v1.1.2 의 extract_bimmodel.process() 호출이 false 를 반환했다. 상위 코드는 이 결과를 받아 즉시 throw 하고 BIM 의 mesh_stateerror 로 전환했다. 클러스터에 해당 fingerprint 의 occurrence 가 1 건만 기록되어 있어 단일 BIM 모델에 대한 일회성 추출 실패다.

Quick Facts#

Field Value
exception.class Error
exception.message forge_bimmodel_extractor failed to extract mesh, process() returned: false
top_frame mesh-extractor.process.ts:150 (production: /tmp/agent/dist/app.cjs:1578)
runtime Node.js child process, @cupix-compute/forge_bimmodel_extractor@1.1.2
env production, region us-west-2, tenant cupix

Affected Teams#

Team / Domain Error Count Impact
secc (mesh extraction) 1 BIM id 20141 의 mesh_state 가 error 로 전환되어 해당 BIM 의 mesh archive 가 S3 에 업로드되지 않음. 다른 BIM 처리에는 영향 없음.

Timeline#

  1. 2026-06-24 16:00:10 KSTBaseService::runByMessage | id: 20141 — SQS message 수신, BIM 20141 처리 시작
  2. 2026-06-24 16:00:11 KSTMeshService::runMeshExtractor | forge_bimmodel_extractor version: 1.1.2 — child process 에서 native extractor 실행
  3. 2026-06-24 16:00:13 KST — child process stderr 에 AWS SDK v2 maintenance notice (extractor 동작과 무관한 노이즈)
  4. 2026-06-24 16:00:16 KSTforge_bimmodel_extractor failed to extract mesh, process() returned: false — native process()false 반환, MeshService::run 의 catch 블록이 error 로깅 후 updateErrorState 호출
  5. 2026-06-24 16:00:16 KSTBaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/20141 + SQS message 삭제로 작업 종료

Error Log#

Datadog Logs

text
MeshService::run | error: {"stack":"Error: forge_bimmodel_extractor failed to extract mesh, process() returned: false
    at ChildProcessManager2.handleMessage (/tmp/agent/dist/app.cjs:1578:26)
    at ChildProcess.<anonymous> (/tmp/agent/dist/app.cjs:1506:16)
    at ChildProcess.emit (node:events:524:28)
    at ChildProcess.emit (node:domain:489:12)
    at emit (node:internal/child_process:950:14)
    at process.processTicksAndRejections (node:internal/process/task_queues:83:21)","message":"forge_bimmodel_extractor failed to extract mesh, process() returned: false"}

Impact#

  • Service: cupixworks-any-mesh-agent
  • Team: secc
  • 발생 횟수: 1
  • 최초 발생: 2026-06-24 16:00:16 KST
  • 최근 발생: 2026-06-24 16:00:16 KST

Root Cause Summary#

Native addon @cupix-compute/forge_bimmodel_extractor@1.1.2 의 동기 extract_bimmodel.process() 호출이 false 를 반환한 것이 근본 원인이다. application 코드는 이 boolean 결과만 보고 즉시 Error 를 throw 하기 때문에 (mesh-extractor.process.ts:150), 추출 실패가 어떤 원인 (Forge URN 가용성, 모델 manifest 미완성, network/Forge API 일시 오류, 네이티브 라이브러리 내부 예외 등) 으로 발생했는지를 application log 만으로는 식별할 수 없다. native addon 은 process status / stderr 로도 의미 있는 진단을 남기지 않았고, application 측 child process stderr 에는 AWS SDK v2 maintenance 경고만 잡혔다. 따라서 1차적인 근본 원인은 native extractor 의 실패 자체이며, 2차적 (시스템적) 근본 원인은 native addon 의 실패 사유를 외부로 전달/로깅하지 않는다는 점이다.

Technical Analysis#

Code Path#

  • Entry point: SQS message → BaseService::runByMessageMeshService::run
  • Mesh extraction dispatch: MeshService::runMeshExtractorMeshExtractManager::execute → child process IPC
  • Failure point: mesh-extractor.process.ts:150process()false 반환 시 throw
packages/cupix-tesla-mesh-agent/src/process/mesh-extractor.process.ts:126-151typescript
if (params.formatType === 'svf2') {
    this.log(`MeshExtractorProcess::execute - forge_bimmodel_extractor params: ${JSON.stringify(params)}`);

    const extractBIMModel = new BIM_MODEL_EXTRACTOR.extract_bimmodel();

    const envName = CPX_ENVIRONMENT_NAME?.toLowerCase();

    this.log(`MeshExtractorProcess::execute - Environment: ${envName}`);

    extractBIMModel.setServer(envName);
    extractBIMModel.setModelUrn(params.urn);
    extractBIMModel.setOutputDirpath(params.path);
    const result = extractBIMModel.process();

    this.log(`MeshExtractorProcess::execute - process() result: ${result} (${typeof result})`);

    if (result === true) {
        const fileList = await CPUtils.getFiles(params.path);
        this.log(`MeshExtractorProcess::execute - extracted ${fileList.length} files: ${JSON.stringify(fileList)}`);
        extract = {
            filepaths: fileList
        };
    } else {
        this.log(`MeshExtractorProcess::execute - extraction failed, result: ${result}`);
        throw new Error(`forge_bimmodel_extractor failed to extract mesh, process() returned: ${result}`);
    }
}

MeshService::run 의 catch 블록은 native error 객체 전체를 JSON.stringify 로 직렬화한 뒤 mesh_stateerror 로 업데이트한다.

packages/cupix-tesla-mesh-agent/src/mesh-service.ts:101-122typescript
protected run = async (targetId: number): Promise<void> => {
    const cpBim = await this.createCPBimByBimId(targetId);
    if (cpBim) {
        this._modelInProcess = cpBim;
        this._forgeApi.updateRegionFromBim(cpBim.forgeRegion);
        if (cpBim.workspaceDirPath) this.setModelWorkspace(cpBim.workspaceDirPath);

        await this.updateBimMeshState(targetId, TESLA.UpdateBimRequest.MeshStateEnum.Extracting);

        try {
            await this.forgeAuth.authenticate();
            await this.runMeshExtractor(cpBim);
            await cpBim.createMeshArchive();
            await cpBim.checkMeshFiles();
            await this.uploadMeshArchiveFileByCPBim(cpBim);
            await this.updateBimMeshState(targetId, TESLA.UpdateBimRequest.MeshStateEnum.Extracted);
        } catch (error) {
            logger.error('MeshService::run | error: %s', JSON.stringify(error, Object.getOwnPropertyNames(error)));
            await this.updateErrorState(cpBim);
        }
    }
};

기대 동작: native process() 가 mesh 파일을 생성하고 true 를 반환하면 후속 archive/upload 가 진행된다. 실제 동작: process()false 를 반환하여 즉시 Error 가 발생, mesh archive 단계 (cpBim.createMeshArchive) 가 한 번도 호출되지 않은 채 catch 블록으로 진입했다. native addon 이 왜 false 를 반환했는지는 노출되지 않는다 (이 native API 는 single boolean 만 반환하고 에러 메시지를 별도로 제공하지 않음 — extract_bimmodel 타입 정의 기준, mesh-extractor.process.ts:18-25).

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-any-mesh-agent status:error @environment:production "MeshService::run"
text
service:cupixworks-any-mesh-agent (from 2026-06-24T06:59:00Z to 2026-06-24T07:02:00Z)

실패 시점 전후 14건 로그 (KST 기준):

text
2026-06-24 16:00:10 info  BaseService::runByMessage | id: 20141
2026-06-24 16:00:10 info  AwsS3Manager::constructor | region: us-west-2
2026-06-24 16:00:11 info  CupixAuth::setSession | session_id: 00e57b0aed25fcdc7f49e8992998398f09930ea0
2026-06-24 16:00:11 info  MeshService::runMeshExtractor | forge_bimmodel_extractor version: 1.1.2
2026-06-24 16:00:13 error ChildProcessManager::setupEventHandlers | Child process stderr: (node:49) NOTE: The AWS SDK for JavaScript (v2) will enter maintenance mode
2026-06-24 16:00:13 error ChildProcessManager::setupEventHandlers | Child process stderr: on September 8, 2024 and reach end-of-support on September 8, 2025.
2026-06-24 16:00:13 error ChildProcessManager::setupEventHandlers | Child process stderr: Please migrate your code to use AWS SDK for JavaScript (v3).
2026-06-24 16:00:13 error ChildProcessManager::setupEventHandlers | Child process stderr: For more information, check blog post at https://a.co/cUPnyil
2026-06-24 16:00:13 error ChildProcessManager::setupEventHandlers | Child process stderr: (Use `node --trace-warnings ...` to show where the warning was created)
2026-06-24 16:00:16 error forge_bimmodel_extractor failed to extract mesh, process() returned: false
2026-06-24 16:00:16 error MeshService::run | error: { ... process() returned: false ... }
2026-06-24 16:00:16 info  BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/20141
2026-06-24 16:00:16 info  AwsQueueManager::deleteMessage | begin - queue url: ...cupix-tesla-mesh-agent-production
2026-06-24 16:00:16 info  AwsQueueManager::deleteMessage | end - message id: 482469f2-70bd-46d6-bc7a-a0776ea4fbd9

관찰:

  • native process() 호출 직후 (16:00:1116:00:16) 약 5초 동안 실행 후 false 반환. timeout (CPX_EXTRACTOR_TIMEOUT) 이 분 단위라면 timeout 은 아니다.
  • stderr 의 AWS SDK v2 warning 은 mesh extraction 자체와 무관한 정상적인 deprecation 노이즈로, 다른 정상 처리 시에도 동일하게 출력됨 (16:34, 16:56, 18:09, ... 의 successful runs 에서도 동일 stderr 가 보이지만 process()true 반환).
  • native library 가 추출 실패 원인을 stderr/stdout/exit code 어디에도 남기지 않음.

같은 6시간 윈도에서 다른 mesh extraction job 들은 정상 처리됨 (예: 16:21:23, 16:24:14, 16:29:10, 16:34:17 등에서 MeshService::runMeshExtractor | forge_bimmodel_extractor version: 1.1.2 직후 정상적으로 MeshService::uploadBimMeshArchiveFile | end 까지 도달). 따라서 native addon 자체가 손상된 것은 아니며 특정 BIM (20141) 의 모델 데이터에 한정된 실패로 보인다.

추가로 같은 6시간 윈도 (16:59:57 KST) 에 Process killed by signal SIGABRT (code: null) 가 한 번 더 관찰됨 — 별도 실패 모드 (native crash) 로, 이 cluster (process() returned: false) 와는 서로 다른 fingerprint 다.

cluster 가 속한 status-board scope svc:cupixworks-any-mesh-agent::unknown 에 같은 날 04:50 KST 에 resolved 된 인시던트가 1건 있지만 (5 clusters 묶음, 모두 root_cause_types: ["unknown"]), 이 cluster 는 11시간 뒤 단일 BIM 에서 발생했고 동일 fingerprint 의 추가 발생이 없어 동일 인시던트 재발이라고 단정할 evidence 는 없다.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Native @cupix-compute/forge_bimmodel_extractor@1.1.2process() 가 BIM 20141 의 특정 모델 상태/데이터로 인해 내부적으로 실패하고 false 를 반환 application log: process() returned: false (mesh-extractor.process.ts:150); 같은 윈도의 다른 BIM 들은 정상 처리됨 native side 의 구체적 실패 사유가 log 로 남지 않음 — 어떤 내부 원인인지는 unverified Confirmed (proximate cause); root sub-cause uncertain — needs verification
H2 Extractor child process 가 timeout (CPX_EXTRACTOR_TIMEOUT) 으로 강제 종료되어 실패 16:00:11 시작 → 16:00:16 실패까지 약 5초만 경과. timeout 은 통상 분 단위. timeout 이었다면 Process killed/SIGTERM 형태로 보고됨 (실제 16:59:57 KST 의 다른 에러가 그 형태) Rejected
H3 Native addon 자체가 손상되었거나 v1.1.2 가 systemic regression 같은 6시간 윈도에서 동일 v1.1.2 로 다수의 BIM 이 정상 추출됨 (16:21, 16:24, 16:29, ...) Rejected
H4 child process stderr 의 AWS SDK v2 deprecation warning 이 실제 실패 원인 stderr 가 status:error 로 분류됨 정상 처리되는 다른 job 들에서도 동일 stderr 가 출력됨. 단순 deprecation 노이즈 Rejected
H5 Forge 인증/네트워크 일시 오류 mesh 추출은 Forge 모델 데이터에 의존 forgeAuth.authenticate()runMeshExtractor 이전에 성공 (MeshService::run 흐름상 throw 시점이 runMeshExtractor 내부). 다만 native side 에서 Forge API 호출이 추가로 발생하는지/그 결과가 어떤지 application log 만으로 확인 불가 Inconclusive — needs verification
H6 같은 svc scope 의 04:50 KST resolved 인시던트 재발 같은 service, 같은 root_cause_type bucket (unknown) 11시간 시간 차이, fingerprint 다름, 단발성 (occurrence_count: 1) Rejected

Fix Recommendation#

즉시 조치 (Critical)#

  • 운영자가 BIM id 20141 의 Forge 모델 상태 (URN, manifest, derivative status) 와 처리 region (us-west-2 production) 을 Autodesk Forge 콘솔/API 로 확인하여 모델 자체에 문제가 있는지 (예: derivative 미완성, manifest 결손) 점검. 단일 BIM 단발 실패이므로 코드 변경 없이 모델 단위 재처리 (re-enqueue) 만으로 해결될 가능성이 높음.
  • 코드 변경 불필요 — root cause 가 native addon 내부에서의 일회성 실패로 추정되고 system-wide regression evidence 가 없음.

단기 개선 (1주 이내)#

  • mesh-extractor.process.ts:138-150 의 진단성 부족 보완 방향: native extract_bimmodelprocess() 외에 마지막 실패 사유 (string/code) 를 노출하는 API (getLastError 등) 를 제공하는지 native package 측에 확인. 제공된다면 process()false 일 때 이를 함께 로깅하도록 logging 방향만 보강 (구현 코드는 본 보고서 범위 밖).
  • 제공되지 않는다면 native package owner (@cupix-compute/forge_bimmodel_extractor maintainer) 에게 실패 사유 노출 (return code/exception/stderr) API 요청.
  • MeshService::run 의 catch 블록에서 JSON.stringify(error, Object.getOwnPropertyNames(error)) 를 사용해 error 를 직렬화하고 있는데, 팀의 logger convention (Error 객체 native 처리) 과 어긋날 수 있음 — 별도 RCA/episode (MEMORY 의 "fix logger" 노트) 와 함께 일관성 검토.

장기 개선 (재발 방지)#

  • BIM 단위 재처리 retry policy 도입: SQS message 가 process() returned: false 로 실패 시 일정 횟수 자동 재시도하고, 동일 BIM 이 N회 연속 실패하면 별도 dead-letter queue / alert 채널로 라우팅.
  • native addon 의 실패 사유 telemetry 표준화 (project-level 의사결정): native side 가 구조화된 실패 코드/메시지를 노출하지 않으면 RCA 가 항상 inconclusive 로 남음. 라이브러리 계약 (interface) 에 실패 사유 필수 노출을 추가 요청.

Monitoring#

  • forge_bimmodel_extractor 실패율 추이 모니터링 (production us-west-2):

    text
    logs("service:cupixworks-any-mesh-agent status:error \"process() returned: false\" @environment:production").index("*").rollup("count").by("region").rollup("count","5m")
    
  • mesh extraction 전체 처리량 대비 실패율 추이 (정상 처리는 MeshService::uploadBimMeshArchiveFile | end 로 마무리됨):

    text
    logs("service:cupixworks-any-mesh-agent \"MeshService::runMeshExtractor | forge_bimmodel_extractor version\" @environment:production").index("*").rollup("count").by("region").rollup("count","5m")
    
  • 같은 BIM id 가 단기간에 반복 실패하는지 감지하려면 BIM id 별 실패 카운트 모니터링 도입을 검토 (현 시점에는 BIM id 가 별도 attribute 로 추출되어 있지 않으므로 log attribute 추출 작업이 선행되어야 함 — uncertain, needs verification).

Risk Assessment#

  • Risk level: low (단발 1건, 동일 service 내 다른 BIM 처리 정상, blast radius = BIM 20141 단일 모델)
  • 예상 복잡도: trivial (운영적 재처리 + 진단성 보강 방향만 권고. 코드 변경은 monitoring/diagnostic 보강 한정)