ES /docs

BimRevisionService::run | error: "BimRevisionService::runBimCompare | end - validation failed (error

RCA: BimRevisionService::runBimCompare | validation failed (errorCode: REV141)

Error Log#

Datadog Logs

text
BimRevisionService::run | error: "BimRevisionService::runBimCompare | end - validation failed (errorCode: REV141)"

Impact#

  • Service: cupixworks-any-bimrevision-agent
  • Team: updatedemo
  • 발생 횟수: 1
  • 최초 발생: 2026-04-06T15:32:12.003Z
  • 최근 발생: 2026-04-06T15:32:12.003Z

Root Cause Summary#

BIM revision 22424 (bimId: 18883, facility: osgj8f)의 Forge BIM 비교 결과, 전체 12,552개 element 중 12,549개가 removed로 판정되었다. 이는 hasExcessiveRemoval 검증의 count threshold(10,000)을 초과하여 안전 장치(REV141)가 발동되었다. 근본 원인은 BIM origin 좌표계 불일치로 추정된다. 기존 BIM origin은 [0,0,0]이었으나, 비교 결과로 계산된 새 origin은 [54.17, 0.19, 17.31]로 크게 달랐다. 이로 인해 Forge comparer가 이전 revision의 element와 현재 revision의 element를 좌표 기반으로 매칭하지 못하고, 거의 모든 element를 "removed"로 분류했다. bypassThresholdfalse로 설정되어 있어 비교 결과가 거부되고 에러 상태로 전환되었다.

Technical Analysis#

Code Path#

  1. Entry point: SQS 메시지 수신 후 BimRevisionService::run 호출

    • bim-revision-service.ts:149targetId: 22424, previousTargetId: 22423
  2. Element 로딩: loadAllElements에서 Tesla API로 element 전체 조회

    • bim-revision-service.ts:320-342
    • 12,552개의 created element 로딩, deleted element 0개
typescript
// bim-revision-service.ts:320-342
private loadAllElements = async (cpBim: CPBim): Promise<void> => {
    logger.info('BimRevisionService::loadAllElements | begin - bimId: %d, facilityKey: %s', cpBim.id, cpBim.facilityKey);
    const srvElements = await this.cupixApi.element.getAll(facilityKey, cpBim.id, undefined, [], undefined);
    // ... 12,552 elements loaded
    const srvRemovedElements = await this.cupixApi.element.getAllRemovedByRevision(cpBim.id);
    // ... 0 removed elements
    logger.info('BimRevisionService::loadAllElements | end - %d cpElements loaded - created: %d, deleted: %d', cpBim.cpElements.size, srvElements.length, srvRemovedElements.length);
};
  1. Threshold 로딩: facility entity parameter에서 threshold 설정 조회

    • bim-revision-service.ts:738-784
    • ratioThreshold: 15%, countThreshold: 10000, bypassThreshold: false
  2. BIM 비교 실행: Forge child process에서 ~6분간 비교 수행

    • bim-revision-service.ts:595-685
    • runBimComparebimCompareManager.execute(params)
  3. 검증 실패: validateBimComparerResult에서 excessive removal 감지

    • cpbim-revision.ts:152-232validateBimComparerResult 호출
    • cpbim-revision.ts:234-265hasExcessiveRemoval 에서 실패 판정
typescript
// cpbim-revision.ts:234-265
private hasExcessiveRemoval = (report: ForgeAgent.Report, cpBim: CPBim, threshold: BimRevisionThreshold): boolean => {
    const forgeRemovedCount = report.removed.length;  // 12,549
    const elementCreatedCount = cpBim.cpElementsCreated.length;  // 12,552
    // ...
    if (forgeRemovedCount >= threshold.countThreshold  // 12,549 >= 10,000 → TRUE
        || (elementCreatedCount > 0 && removedRatio >= threshold.ratioThreshold)) {
        // ...
        if (threshold.bypassThreshold) {  // false → 통과 불가
            return false;
        }
        this._validationErrorCode = ErrorCode.Agent.BimRevisionExcessiveRemoval;  // 'REV141'
        return true;
    }
    return false;
};
  1. 에러 throw: runBimCompare에서 validation 실패 시 에러 전파
    • bim-revision-service.ts:679-682
typescript
// bim-revision-service.ts:679-682
} else {
    const validationErrorCode = cpBimRevision.validationErrorCode ?? ErrorCode.Agent.BimRevisionExtractorInvalidResult;
    this.setErrorCode(validationErrorCode);
    throw new Error(`BimRevisionService::runBimCompare | end - validation failed (errorCode: ${validationErrorCode})`);
}
  1. 상태 업데이트: catch 블록에서 bim_comparison_stateError로 변경
    • bim-revision-service.ts:180-183

Log Evidence#

검색에 사용한 Datadog 쿼리:

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

전체 실행 타임라인 (bim_revision 22424):

시간 (UTC) 레벨 이벤트
15:25:48.439Z INFO BaseService::runByMessage | id: 22424
15:25:48.603Z INFO BimRevisionService::loadAllElements | begin - bimId: 18883, facilityKey: osgj8f
15:26:05.845Z INFO BimRevisionService::loadAllElements | end - 12552 cpElements loaded - created: 12552, deleted: 0
15:26:06.855Z INFO BimRevisionService::loadBimRevisionEntityParameters | threshold - ratio: 15%, count: 10000, bypass: false
15:26:06.798Z INFO BimRevisionService::runBimCompare | begin
15:32:11.992Z INFO CPBimRevision::validateBimComparerResult | modified: 3, removed: 12549, exist: 0
15:32:11.992Z INFO CPBimRevision::validateBimComparerResult | newBimOrigin: 54.17...,0.18...,17.30..., currentOrigin: 0,0,0
15:32:12.003Z ERROR CPBimRevision::validateBimComparerResult | excessive removal detected - bimRevisionId: 22424, bimId: 18883, trigger: count 12549 >= 10000
15:32:12.003Z ERROR CPBimRevision::validateBimComparerResult | elements(total: 12552, created: 12552, deleted: 0) forge(removed: 12549, modified: 3, exist: 0)
15:32:12.003Z ERROR BimRevisionService::run | error: "BimRevisionService::runBimCompare | end - validation failed (errorCode: REV141)"
15:32:12.835Z INFO BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/22424

핵심 로그 — Forge 비교 결과의 origin 불일치:

text
CPBimRevision::validateBimComparerResult | newBimOrigin: 54.17481753183529,0.18898358987644315,17.30648765055639, currentOrigin: 0,0,0

핵심 로그 — excessive removal 감지:

text
CPBimRevision::validateBimComparerResult | excessive removal detected - bimRevisionId: 22424, bimId: 18883, trigger: count 12549 >= 10000
CPBimRevision::validateBimComparerResult | elements(total: 12552, created: 12552, deleted: 0) forge(removed: 12549, modified: 3, exist: 0)

비교: 같은 시간대 다른 BIM revision (22427, team: flintbuilders)은 0개 entity로 정상 완료됨 — 시스템 장애가 아닌 특정 BIM 데이터의 문제.

Fix Recommendation#

즉시 조치 (Critical)#

이 에러는 안전 장치가 정상 작동한 결과이다. 12,549/12,552 element가 removed로 분류된 것은 BIM 비교 결과가 비정상적임을 의미하며, REV141 validation이 데이터 손실을 방지했다.

  • updatedemo 팀(team ID: 643, user: chris.choi@cupix.com)에게 BIM revision 22424 (bimId: 18883, facility: osgj8f)의 비교 실패를 통보
  • 사용자에게 현재 revision과 이전 revision (22423)의 Forge URN이 동일한 BIM 모델의 다른 버전인지 확인 요청
  • Origin [0,0,0] vs 계산된 origin [54.17, 0.19, 17.31]의 큰 차이는 BIM 파일이 다른 좌표계로 업로드되었거나, 잘못된 BIM 파일이 사용된 경우를 시사

단기 개선 (1주 이내)#

  • hasExcessiveRemoval에서 origin 불일치 경고를 추가하는 것이 유용할 수 있음. validateBimComparerResult의 origin 비교 로직(cpbim-revision.ts:172-174)에서 origin 변화가 큰 경우(예: Euclidean distance > threshold), 별도의 경고 로그를 남기면 원인 파악이 빨라짐
  • loadBimRevisionEntityParameters(bim-revision-service.ts:738)에서 facility osgj8fratioThreshold가 15%로 기본값(40%)보다 낮게 설정되어 있으나, 이 경우 count threshold(10,000)에 먼저 도달하므로 ratio threshold는 무관

장기 개선 (재발 방지)#

  • Forge BIM comparer에서 origin 기반 사전 검증 단계를 추가 — 비교 전에 두 revision의 bounding box나 origin을 비교하여, 좌표계 불일치가 의심되면 비교 자체를 건너뛰고 명확한 에러 코드를 반환
  • REV141 발생 시 사용자에게 자동 알림을 보내는 기능 (현재는 bim_comparison_state가 Error로 변경되지만, 사용자 대면 알림은 별도 구현 필요)

Monitoring#

  • REV141 에러 발생 빈도 추적:
text
service:cupixworks-any-bimrevision-agent status:error "REV141"
  • BIM origin 큰 변화 감지 (origin 불일치가 반복되는지 확인):
text
service:cupixworks-any-bimrevision-agent "validateBimComparerResult" "newBimOrigin"

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial — 안전 장치가 정상 작동한 사례이며, 데이터 손실은 발생하지 않음. BIM revision 22424의 bim_comparison_stateError로 설정되어 사용자가 재시도할 수 있음. 근본 원인은 입력 데이터(BIM 파일)의 좌표계 문제로 코드 수정보다는 데이터 확인이 필요.