ES /docs

BIM revision removal ratio exceeds configured threshold

RCA: CPBimRevision::validateBimComparerResult | excessive removal detected

Overview#

What Happened#

2026-05-07 09:15:04 UTC, cupixworks-any-bimrevision-agent 서비스에서 bimRevisionId 4741 (bimId 1943, facilityKey 8quehh)의 BIM 비교 결과가 facility 전용 removal threshold (15%)를 초과하여 검증 실패. Forge 비교 결과 7045개 element 중 1803개가 removed (25.6%)로 판정됨.

Quick Facts#

Field Value
exception.class Validation Guard (hasExcessiveRemoval)
exception.message excessive removal detected - bimRevisionId: 4741, bimId: 1943, trigger: ratio 25.6% >= 15%
top_frame cpbim-revision.ts:243
env production, ap-southeast-2

Affected Teams#

Team / Domain Error Count Impact
takenaka-vsmc 1 BIM revision 비교 결과 미적용, 상태 Error로 전환

Timeline#

  1. 09:13:46Z — SQS 메시지 수신, bimRevisionId 4741 처리 시작
  2. 09:13:53Z — 7045개 element 로드 완료 (created: 7045, deleted: 0)
  3. 09:13:54Z — Forge BIM 비교 시작 (version 39 → version 102)
  4. 09:15:04Z — 비교 완료: modified 5242, removed 1803, exist 0
  5. 09:15:04ZhasExcessiveRemoval 검증 실패 (25.6% >= 15%), errorCode REV141 설정
  6. 09:15:05Z — workspace 정리 및 메시지 삭제

Error Log#

Datadog Logs

text
CPBimRevision::validateBimComparerResult | excessive removal detected - bimRevisionId: 4741, bimId: 1943, trigger: ratio 25.6% >= 15%

Impact#

  • Service: cupixworks-any-bimrevision-agent
  • Team: takenaka-vsmc
  • 발생 횟수: 1
  • 최초 발생: 2026-05-07T09:15:04.357Z
  • 최근 발생: 2026-05-07T09:15:04.357Z

Root Cause Summary#

Facility 8quehh (takenaka-vsmc 팀)에 설정된 커스텀 bim_revision_removed_ratio_threshold 값이 15%로, 기본값(40%)보다 매우 엄격함. BIM 모델이 version 39에서 version 102로 대규모 업데이트되면서 Forge 비교 결과 1803/7045개(25.6%) element가 removed로 판정됨. 이는 코드 버그가 아니라 의도된 안전 가드가 정상 작동한 것으로, 대규모 모델 변경 시 잘못된 대량 삭제를 방지하기 위한 validation threshold를 초과한 경우임.

Technical Analysis#

Code Path#

  • Entry point: bim-revision-service.ts:150run() 메서드에서 SQS 메시지 처리
  • Element 로드: bim-revision-service.ts:328loadAllElements() 7045개 element 로드
  • BIM 비교 실행: bim-revision-service.ts:603runBimCompare() Forge 비교 프로세스 호출
  • Threshold 로드: bim-revision-service.ts:746loadBimRevisionEntityParameters() facility entity parameters에서 커스텀 threshold 조회
  • Validation: cpbim-revision.ts:152validateBimComparerResult() 비교 결과 검증
  • Failure point: cpbim-revision.ts:243hasExcessiveRemoval() ratio 초과 판정
cpbim-revision.ts:234-265typescript
private hasExcessiveRemoval = (report: ForgeAgent.Report, cpBim: CPBim, threshold: BimRevisionThreshold): boolean => {
    const forgeRemovedCount = report.removed.length;
    const elementCreatedCount = cpBim.cpElementsCreated.length;
    const removedRatio = elementCreatedCount > 0 ? (forgeRemovedCount / elementCreatedCount) * 100 : 0;

    if (forgeRemovedCount >= threshold.countThreshold || (elementCreatedCount > 0 && removedRatio >= threshold.ratioThreshold)) {
        const logLevel = threshold.bypassThreshold ? 'warn' : 'error';
        const trigger = forgeRemovedCount >= threshold.countThreshold ? `count ${forgeRemovedCount} >= ${threshold.countThreshold}` : `ratio ${removedRatio.toFixed(1)}% >= ${threshold.ratioThreshold}%`;
        logger[logLevel](
            'CPBimRevision::validateBimComparerResult | excessive removal detected - bimRevisionId: %d, bimId: %d, trigger: %s',
            this.id, cpBim.id, trigger
        );

        if (threshold.bypassThreshold) {
            logger.warn('CPBimRevision::validateBimComparerResult | bypass enabled, continuing');
            return false;
        }

        this._validationErrorCode = ErrorCode.Agent.BimRevisionExcessiveRemoval;
        return true;
    }

    return false;
};

실제 동작:

  • elementCreatedCount = 7045, forgeRemovedCount = 1803
  • removedRatio = (1803 / 7045) * 100 = 25.6%
  • threshold.ratioThreshold = 15% (facility 커스텀 값)
  • threshold.bypassThreshold = false → 검증 실패로 에러 반환
bim-revision-service.ts:680-691typescript
if (cpBimRevision.validateBimComparerResult(bimCompareResults, threshold)) {
    this.updateBimModelsFromComparison(cpBimRevision, report);
    if (!cpBimRevision.saveBimRevisionResults()) {
        this.setErrorCode(ErrorCode.Agent.BimRevisionFailedToSaveResult);
        throw new Error('BimRevisionService::runBimCompare | end - failed to save bim compare results');
    }
} else {
    const validationErrorCode = cpBimRevision.validationErrorCode ?? ErrorCode.Agent.BimRevisionExtractorInvalidResult;
    this.setErrorCode(validationErrorCode);
    throw new Error(`BimRevisionService::runBimCompare | end - validation failed (errorCode: ${validationErrorCode})`);
}

Log Evidence#

검색 쿼리:

text
service:cupixworks-any-bimrevision-agent status:(info OR warn OR error) (4741 OR 1943)
Time: 2026-05-07T09:13:00Z to 2026-05-07T09:16:00Z

핵심 로그 타임라인:

text
18:13:46 KST [info] BaseService::runByMessage | id: 4741
18:13:46 KST [info] BimRevisionService::loadAllElements | begin - bimId: 1943, facilityKey: 8quehh
18:13:53 KST [info] BimRevisionService::loadAllElements | end - 7045 cpElements loaded - created: 7045, deleted: 0
18:13:54 KST [info] BimRevisionService::loadBimRevisionEntityParameters | threshold - ratio: 15%, count: 10000, bypass: false
18:13:54 KST [info] BimRevisionService::runBimCompare | params - urn: dXJuOmFkc2...dmVyc2lvbj0xMDI=, previousUrn: dXJuOmFkc2...dmVyc2lvbj0zOQ==
18:15:04 KST [info] BimRevisionService::runBimCompare | report.modified.length: 5242, report.removed.length: 1803, report.exist.length: 0
18:15:04 KST [error] CPBimRevision::validateBimComparerResult | excessive removal detected - bimRevisionId: 4741, bimId: 1943, trigger: ratio 25.6% >= 15%
18:15:04 KST [error] CPBimRevision::validateBimComparerResult | elements(total: 7045, created: 7045, deleted: 0) forge(removed: 1803, modified: 5242, exist: 0)
18:15:04 KST [error] BimRevisionService::run | error: "BimRevisionService::runBimCompare | end - validation failed (errorCode: REV141)"
18:15:05 KST [info] BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/4741

비교 대상: 동일 Forge 파일의 version 39 → version 102 (Base64 decoded URN에서 확인). 82개 major version이 건너뛰어진 대규모 업데이트.

참고: bimRevisionId 4742 (같은 facility의 다른 BIM)는 동일 시간대에 0개 element로 성공적으로 비교 완료됨 (siteinsights 미사용 모델).

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Facility 커스텀 threshold(15%)가 대규모 모델 변경에 비해 지나치게 엄격함 로그에서 threshold - ratio: 15% 확인. 기본값은 40%. Version 39→102 간 대규모 변경으로 25.6% removed 발생 Confirmed
H2 Forge 비교 알고리즘 오류로 잘못된 removed 판정 비교 자체는 정상 완료 (no Forge error code). 5242 modified + 1803 removed = 7045 (전체 element) origin 좌표 변경, view 매핑 모두 정상 처리됨 Rejected
H3 bypassThreshold가 true여야 하는데 잘못 설정됨 bypassThreshold: false는 facility entity parameters에서 의도적으로 설정된 값이며, 이 threshold는 대량 삭제 방지 목적의 안전 가드 Inconclusive

Fix Recommendation#

즉시 조치 (Critical)#

  • 코드 수정 불필요 — 이 에러는 의도된 안전 가드가 정상 작동한 결과
  • Facility 8quehh의 entity parameter bim_revision_removed_ratio_threshold를 25.6%를 수용할 수 있도록 30% 이상으로 상향 조정하거나, 이번 revision에 한해 bim_revision_bypass_thresholdtrue로 설정 후 재처리 고려
  • 모델 version 39→102 사이의 대규모 변경이 의도된 것인지 takenaka-vsmc 팀에 확인 필요

단기 개선 (1주 이내)#

  • 이 에러를 error 대신 warn 레벨로 로깅하는 것을 검토. hasExcessiveRemoval은 의도된 validation guard이므로 검증 실패 자체가 시스템 오류는 아님. bypassThreshold: false일 때도 로그 레벨을 warn으로 변경하면 error monitoring 노이즈를 줄일 수 있음
  • 또는 Datadog에서 "excessive removal detected" 메시지를 별도 모니터로 분류하여 일반 error alert에서 제외

장기 개선 (재발 방지)#

  • Facility별 threshold 설정 현황을 대시보드로 관리하여 모델 변경 규모 대비 적절한 threshold가 설정되어 있는지 주기적으로 검토
  • Version gap이 큰 경우(예: 10+ versions) 자동으로 threshold를 완화하거나 관리자 알림을 보내는 로직 검토

Monitoring#

  • 현재 모니터링은 error 로그 수집으로 충분
  • 추가 제안: facility별 excessive removal 발생 빈도 추적
text
service:cupixworks-any-bimrevision-agent "excessive removal detected" @environment:production

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial (threshold 조정만으로 해결 가능, 코드 변경 불필요)