ES /docs

BimRevisionService::runBimCompare | Critical Forge error detected - forgeErrorCode: 908, mapped to r

RCA: BimRevisionService::runBimCompare — Critical Forge error 908 (REV908)

Overview#

What Happened#

cupixworks-any-bimrevision-agent이 BIM 모델 비교(runBimCompare)를 수행하는 도중 forge child process가 forgeErrorCode: 908을 반환하여 revision이 실패했다. 908은 "source/target 모델의 bounding box가 비교 한계(5000m)를 초과해 floating-point 정밀도 문제로 비교 신뢰성이 떨어진다"는 검증성 에러로, agent 측 결함이 아니라 입력 BIM 모델의 좌표/스케일 문제가 원인이다.

Quick Facts#

Field Value
exception.class Error (generic Node.js Error thrown by runBimCompare)
exception.message BimRevisionService::runBimCompare | Forge error: 908 - The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m). ...
top_frame packages/cupix-tesla-bim-revision-agent/src/bim-revision-service.ts:670
revisionErrorCode REV908 (via ForgeErrorMapper.mapForgeErrorToRevisionError)
env production, regions us-west-2, eu-central-1
tenant cupix

Affected Teams#

Team / Domain Error Count Impact
exyte (BIM Revision pipeline) 2 두 건의 revision 작업 실패 — 해당 facility는 BIM 비교/변경 추적 결과를 받지 못함

지난 7일 범위에서 동일 forgeErrorCode: 908 패턴이 다수 발생 (bim_id 1243, 19944, 19753, 19944, 16489 등). 본 cluster에 포함된 2건 외에도 동일 root cause로 추정되는 이벤트가 다수 있음.

Timeline#

  1. 2026-06-24 17:09 KSTbim_id=16489, src_revision_id=24603 비교 시작 → forge child process가 Error code 908 반환 (source extent 5011.2m, limit 5000m). BimRevisionService::runBimCompare가 throw → REVISE-END status=error.
  2. 2026-06-24 18:08 KST — 동일 cluster의 두 번째 이벤트. 이번에는 forgeErrorCode: INVALID_OTG_ERROR (REV1로 매핑). 메시지 템플릿이 같아 fingerprint가 동일하게 grouping됨.
  3. 2026-06-24 13:44 ~ 13:47 KST — 동일 서비스의 별도 incident(2026-06-24-svc-cupixworks-any-bimrevision-agent--unknown-1)가 약 4시간 전에 자동 감지/해제됨. root_cause_types: unknown — 본 cluster와 직접 관련 여부 미확인.

Error Log#

Datadog Logs

text
BimRevisionService::runBimCompare | Critical Forge error detected - forgeErrorCode: 908, mapped to revisionErrorCode: REV908

Impact#

  • Service: cupixworks-any-bimrevision-agent
  • Team: exyte
  • 발생 횟수: 2
  • 최초 발생: 2026-06-24 17:09 KST
  • 최근 발생: 2026-06-24 18:08 KST

영향 규모는 작지만(2건), 동일 root cause(forgeErrorCode: 908)는 지난 7일간 다수 facility에서 반복적으로 관찰됨. 영향 범위는 "비정상적으로 큰 좌표 스케일을 가진 BIM 모델을 업로드한 사용자"로 한정된다.

Root Cause Summary#

runBimCompare가 호출하는 forge child process(@cupix/forge-agents의 BIM Comparer)가, 입력된 source 또는 target SVF/OTG 모델의 bounding box max extent가 5000m 한계를 초과한 것을 감지하고 Error code 908을 반환한다. bim-revision-agent는 이 코드를 ForgeErrorMapper.mapForgeErrorToRevisionErrorREV908에 매핑한 뒤 logger.error(... Critical Forge error detected ...)를 출력하고 throw하므로, 에러 자체는 검증 로직이 정상적으로 동작한 결과이다. 즉 에이전트 결함이 아니라 입력 데이터(BIM 모델의 좌표계/스케일) 문제가 root cause이며, 단지 그 상황이 status:error 로그로 보고되기 때문에 error-sweeper가 클러스터로 묶었다.

Technical Analysis#

Code Path#

  • Entry point: packages/cupix-tesla-bim-revision-agent/src/bim-revision-service.ts:603runBimCompare(cpBimRevision, cpPreviousBimRevision)
  • Forge 호출: bim-revision-service.ts:647this.bimCompareManager.execute(params) (child process를 통해 @cupix/forge-agents 의 BIM Comparer 실행)
  • 결과 분기: bim-revision-service.ts:657-672bimCompareResults.Error를 읽어 ignorable / critical 판정
  • Failure point: bim-revision-service.ts:667-670mapForgeErrorToRevisionError(908)REV908 매핑 후 logger.error와 함께 throw
  • Mapper: packages/cupix-tesla-bim-revision-agent/src/util/forge-error-mapper.ts:33-39
packages/cupix-tesla-bim-revision-agent/src/bim-revision-service.ts:647-672typescript
const bimCompareResults = await this.bimCompareManager.execute(params);
const newBimOrigin = bimCompareResults?.Origin;
const report = bimCompareResults?.Compare;

if (report) {
    logger.debug('BimRevisionService::runBimCompare | report.modified: %s', JSON.stringify(report.modified.map(m => ({ modelId: m.modelId, dbId: m.dbId }))));
    logger.debug('BimRevisionService::runBimCompare | report.removed: %s', JSON.stringify(report.removed));
    logger.debug('BimRevisionService::runBimCompare | report.exist: %s', JSON.stringify(report.exist.map(e => e != undefined ? { modelId: e.modelId, dbId: e.dbId } : null)));
}

const forgeErrorCode = bimCompareResults?.Error;
const forgeErrorMessage = bimCompareResults?.ErrorMessage;

if (forgeErrorCode) logger.warn('CPBimRevision::validateBimComparerResult | forgeErrorCode: %s', forgeErrorCode?.toString());
if (forgeErrorMessage) logger.warn('CPBimRevision::validateBimComparerResult | forgeErrorMessage: %s', forgeErrorMessage?.toString());

if (forgeErrorCode) {
    if (ForgeErrorMapper.isIgnorableError(forgeErrorCode)) {
        logger.warn('BimRevisionService::runBimCompare | Ignorable Forge error detected - forgeErrorCode: %s, message: %s', forgeErrorCode, forgeErrorMessage);
    } else {
        const errorCode = ForgeErrorMapper.mapForgeErrorToRevisionError(forgeErrorCode);
        logger.error('BimRevisionService::runBimCompare | Critical Forge error detected - forgeErrorCode: %s, mapped to revisionErrorCode: %s', forgeErrorCode, errorCode);
        this.setErrorCode(errorCode);
        throw new Error(`BimRevisionService::runBimCompare | Forge error: ${forgeErrorCode} - ${forgeErrorMessage}`);
    }
}
packages/cupix-tesla-bim-revision-agent/src/util/forge-error-mapper.ts:19-39typescript
/** Forge error codes that do not require stopping the revision process */
private static ignorableErrorCodes: Set<ForgeAgentErrorCode> = new Set([
    ForgeAgentErrorCode.ROOM_EXT_ROOM_MAKER_IS_NOT_DEFINED
]);

static mapForgeErrorToRevisionError(forgeErrorCode: ForgeAgentErrorCode | any): string {
    if (Object.values(ForgeAgentErrorCode).includes(forgeErrorCode)) {
        return ErrorCode.Revision.statusCode(forgeErrorCode);
    }
    logger.warn('ForgeErrorMapper::mapForgeErrorToRevisionError | Unmapped forge error code detected - forgeErrorCode: %s, type: %s, mapping to UNKNOWN (REV1)', forgeErrorCode, typeof forgeErrorCode);
    return ErrorCode.Revision.statusCode(ForgeAgentErrorCode.UNKNOWN);
}

기대 동작과 실제 동작이 일치한다: bounding box가 한계를 초과하는 입력에 대해 forge가 검증 에러를 돌려주면 agent는 그것을 REV908로 매핑·기록한 뒤 revision을 중단한다. 다만 현재 코드는 이 "사용자 입력 문제"를 logger.error로 기록하여 Datadog에서는 시스템 결함처럼 보이게 된다 (이것이 cluster를 만든 직접 원인).

ignorableErrorCodes set에는 현재 ROOM_EXT_ROOM_MAKER_IS_NOT_DEFINED만 포함돼 있어 COMPARE_EXT_* 계열 입력 검증 실패는 모두 critical path로 빠진다 (forge-error-mapper.ts:20-22).

Log Evidence#

Datadog query (cluster URL 기준, 14일 retention 범위 내):

text
service:cupixworks-any-bimrevision-agent status:error @environment:production "BimRevisionService::runBimCompare"

확장 쿼리 (지난 7일):

text
service:cupixworks-any-bimrevision-agent "bounding box is too large"

핵심 로그 (cluster 이벤트):

text
2026-06-24 17:09:06  error  BimRevisionService::runBimCompare | Critical Forge error detected - forgeErrorCode: 908, mapped to revisionErrorCode: REV908
2026-06-24 17:09:06  error  BimRevisionService::run | error: "BimRevisionService::runBimCompare | Forge error: 908 - The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m). Large models cause floating-point precision issues that make comparison unreliable."
2026-06-24 17:09:06  warn   CPBimRevision::validateBimComparerResult | forgeErrorMessage: The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m). ...
2026-06-24 17:09:06  error  ChildProcessManager::setupEventHandlers | Child process stderr: ForgeAgentError: The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m). ...
2026-06-24 18:08:39  error  BimRevisionService::runBimCompare | Critical Forge error detected - forgeErrorCode: INVALID_OTG_ERROR, mapped to revisionErrorCode: REV1
2026-06-24 18:08:39  error  BimRevisionService::run | error: "BimRevisionService::runBimCompare | Forge error: INVALID_OTG_ERROR - OTG status is failed: [{\"type\":\"error\",\"message\":\"Extractor error code -777\",\"code\":\"TranslationWorker-InternalFailure\"}]"

REVISE-END info 로그(JSON)에서 영향 받은 entity ID를 확인할 수 있다:

json
{
  "bim_id": 16489,
  "src_revision_id": 24603,
  "prev_revision_id": 21799,
  "si_trace_id": "763b8c34-5ce4-456d-9117-208a2cbf160e",
  "elapsed_ms": 6773,
  "status": "error",
  "error_message": "BimRevisionService::runBimCompare | Forge error: 908 - The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m). ...",
  "counts": {"total":0,"modified":0,"removed":0,"exist":0}
}

7일 패턴 (동일 root cause 다발):

text
2026-06-23 20:57:49  bim_id=1243   target extent 79903.2m
2026-06-23 04:08:31  bim_id=1243   target extent 79903.2m
2026-06-20 05:36:45  bim_id=19944  source extent 529197.5m
2026-06-19 23:15:49  bim_id=19753  target extent 1329398.3m
2026-06-24 17:09:06  bim_id=16489  source extent 5011.2m

extent 5011.2m처럼 한계에 매우 근접한 경우(0.2% 초과)부터 1,329,398m(약 1,329km, 좌표계 잘못 적용 의심)까지 폭넓게 나타난다.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Forge child process가 입력 모델의 bounding box max extent > 5000m를 감지하여 코드 908을 반환 → agent가 REV908로 매핑·throw ChildProcessManager::setupEventHandlers | Child process stderr: ForgeAgentError: The source model bounding box is too large for reliable comparison (max extent: 5011.2m, limit: 5000m) 로그. bim-revision-service.ts:667-670에서 ForgeErrorMapper.mapForgeErrorToRevisionError(908)REV908 throw. forge-error-mapper.ts:34 Object.values(ForgeAgentErrorCode).includes(908) 매핑. Confirmed
H2 bim-revision-agent의 코드 결함 (null reference, race condition 등)으로 인한 시스템 에러 로그가 정확한 에러 메시지(bounding box too large)와 수치(max extent: 5011.2m, limit: 5000m)를 동반함. 코드 경로(bim-revision-service.ts:603-693)는 forge 결과를 그대로 매핑/throw할 뿐 검증 로직 자체에 결함 없음. isIgnorableError/mapForgeErrorToRevisionError는 단위 테스트가 존재(__tests__/util/forge-error-mapper.spec.ts). Rejected
H3 Forge API 서비스 장애로 인한 false positive (실제 모델은 정상인데 잘못 908 반환) 다양한 bim_id(1243, 16489, 19753, 19944)에서 일관되게 발생하며, 5011.2m / 79903.2m / 529197.5m / 1329398.3m 등 한계와 무관하게 모델별 고유 extent 수치가 보고됨. 단순 서비스 장애라면 동일 extent 수치가 반복되거나 다른 에러 코드가 섞여야 함. Rejected
H4 상위 서비스 incident(2026-06-24-svc-cupixworks-any-bimrevision-agent--unknown-1, ~04:44 UTC 해제)와 연관된 잔여 영향 동일 서비스의 별도 cluster 다수가 같은 날 발생 → 자동 incident 생성 후 resolved. 시간 간격이 4시간 이상이고, 본 cluster의 에러는 입력 데이터 검증 에러로 incident의 미지(unknown) root cause와 인과 관계가 보이지 않음. status-board 자체도 active: null. Rejected

Fix Recommendation#

즉시 조치 (Critical)#

본 클러스터는 시스템 결함이 아닌 입력 데이터 문제다. 코드 수정 없이 운영 측면에서 처리하면 된다.

  1. exyte 팀에 해당 BIM 모델(bim_id=16489src_revision_id=24603)을 공유하여, 모델 좌표계/스케일 문제(extent 5011.2m, 한계 5000m에 매우 근접 — 0.2% 초과)를 사용자에게 안내하고 모델 origin 보정 또는 재업로드 요청.
  2. 동일 root cause(forgeErrorCode: 908)로 실패한 다른 facility 케이스(bim_id 1243, 19753, 19944)도 함께 정리 — 동일한 사용자 행동 패턴인지 확인.

단기 개선 (1주 이내)#

  1. 로그 레벨 조정: runBimCompare에서 forge가 돌려준 검증성 에러(COMPARE_EXT 계열, OTG 변환 실패 등) 중 "입력 데이터 문제로 명확히 판정된 코드"는 logger.error 대신 logger.warn으로 낮춘다. 위치: packages/cupix-tesla-bim-revision-agent/src/bim-revision-service.ts:668. 이렇게 하면 error-sweeper 클러스터가 생성되지 않아 운영 노이즈를 줄일 수 있다 (참고: MEMORY.md의 "RCA Quality Patterns — 본 케이스는 입력 데이터 문제로 expected operational scenario에 해당").
  2. 에러 분류 명확화: 현재 ignorableErrorCodesROOM_EXT_ROOM_MAKER_IS_NOT_DEFINED 1개뿐이다. COMPARE_EXT_*, INVALID_OTG_ERROR, INVALID_ARGUMENT_* 같은 사용자 입력 검증 실패 코드를 별도 "user-input-error" 카테고리로 분리하고, agent log에서는 warn으로 기록하되 Tesla API에는 그대로 REV 코드로 전달하는 구조 검토. 위치: packages/cupix-tesla-bim-revision-agent/src/util/forge-error-mapper.ts:20-22.

장기 개선 (재발 방지)#

  1. 업로드 단계 사전 검증: Forge로 보내기 전, BIM 모델의 bounding box extent를 API/UI에서 미리 측정하여 5000m 한계 초과 시 사용자에게 즉시 명확한 에러 메시지를 제공. revision 파이프라인 끝에서 실패하기보다 업로드 시점에서 차단하는 편이 사용자 경험과 비용 모두 유리.
  2. revision 실패 코드 대시보드: REVISE-END JSON 로그(status:"error" + error_message)를 기반으로 REV 코드별 실패 분포를 Datadog dashboard로 시각화하여, 시스템 에러(REV1/REV101 등)와 사용자 입력 에러(REV908, REV141 등)를 분리 모니터링.

Monitoring#

이미 충분한 로그가 남고 있다. 다음 쿼리를 dashboard timeseries widget에 등록하면 동일 패턴을 추적할 수 있다.

REV908 (bounding box 한계 초과) 발생률:

text
service:cupixworks-any-bimrevision-agent status:error "revisionErrorCode: REV908"

전체 BimRevision critical forge error 발생률 (REV* 매핑된 모든 케이스):

text
service:cupixworks-any-bimrevision-agent status:error "Critical Forge error detected"

bounding box too large 메시지 (모든 status):

text
service:cupixworks-any-bimrevision-agent "bounding box is too large"

REVISE-END status=error count (성공/실패 비율 측정용):

text
service:cupixworks-any-bimrevision-agent "BimRevisionService::REVISE-END" "\"status\":\"error\""

Risk Assessment#

  • Risk level: low — 시스템 결함이 아닌 사용자 입력 데이터 문제. 영향 범위는 비정상적으로 큰 좌표 스케일의 BIM을 업로드한 사용자에 한정.
  • 예상 복잡도: trivial — 코드 변경 불필요. 운영 안내 + 단기적으로 log level 낮춤(1줄 변경) 정도. 사전 검증 도입은 별도 ticket으로 분리 권장.