ES /docs

PreprocessorService::run | end

RCA: PreprocessorService::run | end

Overview#

What Happened#

2026-04-21 12:38:35 UTC에 cupixworks-sitetrack-preprocessor-agent 서비스에서 sitetrack 16710 (job 1026434)의 전처리 과정 중 BIM 모델 유효성 검증이 실패하여 PreprocessorService::run이 에러 레벨로 종료되었다. 해당 facility의 모든 BIM 모델이 mesh_state: extracted 조건을 충족하지 못해 전처리가 중단된 것이다.

Quick Facts#

Field Value
exception.message None of the bim mesh_states are extracted
top_frame base-preprocessor-runner.ts:58
env production, us-west-2

Affected Teams#

Team / Domain Error Count Impact
gad (team_id: 590) 1 sitetrack 16710 전처리 실패, 후속 분석 파이프라인 미실행

Timeline#

  1. 2026-04-21T12:38:35.434Z — Job 1026434 시작, load_sitetrack_on_preprocessor 단계 진입
  2. 2026-04-21T12:38:35.465Zload_target_models 단계 진입, createCPBims 실행
  3. 2026-04-21T12:38:35.605ZvalidatesCPBims 실패: "None of the bim mesh_states are extracted"
  4. 2026-04-21T12:38:35.605ZPreprocessorService::run | end 에러 레벨 로그, updateErrorActionJob 호출
  5. 2026-04-21T12:38:35.605Z — 작업 공간 정리 (/tmp/workspace/16710)

Error Log#

Datadog Logs

text
PreprocessorService::run | end

Impact#

  • Service: cupixworks-sitetrack-preprocessor-agent
  • Team: gad
  • 발생 횟수: 1 (이 클러스터), 단 동일 패턴이 14일간 10건 이상 반복 발생
  • 최초 발생: 2026-04-21T12:38:35.605Z
  • 최근 발생: 2026-04-21T12:38:35.605Z

Root Cause Summary#

Sitetrack 16710의 facility에 등록된 BIM 모델 중 mesh_stateextracted이면서 published_at이 존재하는 BIM이 하나도 없었다. createCPBims()가 API에서 BIM 목록을 가져온 뒤 이 두 조건으로 필터링하면 빈 배열이 반환되고, 이후 validatesCPBims()에서 cpParent.cpBims.length === 0 조건에 걸려 rejection이 발생한다. 이 rejection은 PreprocessorService::run의 catch 블록에서 잡혀 error 레벨 로그로 기록된다. 이는 데이터 전제 조건 미충족으로 인한 예상 가능한 실패 시나리오이며, 코드 버그라기보다는 사용자 데이터 상태 문제이다.

Technical Analysis#

Code Path#

  • Entry point: preprocessor-service.ts:49PreprocessorService::run 시작
  • preprocessor-service.ts:52jobManager.loadJob(targetId)로 job 1026434 로드
  • preprocessor-service.ts:64createCPSitetrack(srvJob)으로 sitetrack 16710 객체 생성
  • preprocessor-service.ts:71runner.createTargetModels(cpSitetrack) 호출
preprocessor-service.ts:69-73typescript
let start = Date.now();
await this.jobManager.updateJobProgress(7, 'load_target_models');
await runner.createTargetModels(cpSitetrack);
await runner.validateTargetModels(cpSitetrack);
this.logDuration(start, Date.now(), `load_target_models - sitetrack_id: ${cpSitetrack.id}, job_id: ${targetId}`);
  • sitetrack-preprocessor-runner.ts:11createCPBims(cpSitetrack) 호출하여 BIM 모델 로드
sitetrack-preprocessor-runner.ts:9-12typescript
async createTargetModels(cpSitetrack: CPSitetrack): Promise<void> {
	logger.debug('SiteTrackPreprocessorRunner::createTargetModels | begin');
	const cpBims = await this.createCPBims(cpSitetrack);
	await this.validatesCPBims(cpSitetrack);
  • base-preprocessor-runner.ts:45-47 — API에서 BIM 가져오되 mesh_state === 'extracted'published_at 존재 여부로 필터링
base-preprocessor-runner.ts:45-51typescript
const candidateBims = this.cupixApi.bim.getAll(facilityKey, useSiteinsights)
	.then(bims => bims.filter(bim => bim.mesh_state === 'extracted'))
	.then(bims => bims.filter(bim => bim.published_at));
const cpBims = await createModels(CPBim, cpParent, candidateBims);

logger.debug('BasePreprocessorRunner::createCPBims | end - bim count: %d, bim ids: [%s]', cpBims.length, cpBims.map(bim => bim.id).join(', '));
return cpBims;
  • Failure point: base-preprocessor-runner.ts:58cpParent.cpBims.length === 0이면 reject
base-preprocessor-runner.ts:54-65typescript
validatesCPBims = (cpParent: SiteinsightParentModel): Promise<void> => new Promise((resolve, reject) => {
	logger.debug('BasePreprocessorRunner::validatesCPBims | begin');
	this.jobManager.setErrorCode(ErrorCode.Agent.DeviationBimMeshNotExtractedState);

	if (cpParent.cpBims.length === 0) {
		logger.warn('BasePreprocessorRunner::validatesCPBims | end - None of the bim mesh_states are extracted');
		return reject('None of the bim mesh_states are extracted');
	}

	logger.debug('BasePreprocessorRunner::validatesCPBims | end');
	resolve();
});
  • preprocessor-service.ts:94-96 — catch 블록에서 error 로그 기록 및 에러 상태 업데이트
preprocessor-service.ts:94-96typescript
} catch (error) {
	logger.error('PreprocessorService::run | end', error);
	await this.jobManager.updateErrorActionJob(this.ActionName);
}

기대 동작: BIM 모델이 extracted 상태이고 published_at이 있으면 정상적으로 전처리가 진행됨. 실제 동작: sitetrack 16710의 facility에 해당 조건을 만족하는 BIM이 없어 validatesCPBims에서 rejection → catch 블록에서 error 레벨 로그.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-sitetrack-preprocessor-agent 1026434

Job 1026434의 전체 실행 흐름 (시간순):

text
12:38:35.434Z [info]  BaseService::runByMessage | id: 1026434
12:38:35.434Z [info]  CupixAuth::setSession | session_id: 4c5e46c15248f009a97f1e3857475bbf8afa46f1
12:38:35.434Z [info]  PreprocessorService::run | begin
12:38:35.434Z [info]  JobManager::loadJob | begin - job id: 1026434
12:38:35.434Z [info]  JobManager::loadJob | end - job id: 1026434
12:38:35.434Z [warn]  JobManager::updateJobProgress | skipped - progress: 5, status: load_sitetrack_on_preprocessor
12:38:35.434Z [info]  PreprocessorService::createCPSitetrack | begin - sitetrackId: 16710
12:38:35.434Z [info]  PreprocessorService::createCPSitetrack | end
12:38:35.465Z [warn]  JobManager::updateJobProgress | skipped - progress: 7, status: load_target_models
12:38:35.605Z [warn]  BasePreprocessorRunner::validatesCPBims | end - None of the bim mesh_states are extracted
12:38:35.605Z [error] PreprocessorService::run | end
12:38:35.605Z [info]  PreprocessorService::run | end
12:38:35.605Z [info]  BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/16710
12:38:35.605Z [info]  AwsQueueManager::deleteMessage | begin
12:38:35.605Z [info]  AwsQueueManager::deleteMessage | end

핵심 포인트:

  • load_target_models 단계 진입 후 ~140ms 만에 BIM 검증 실패
  • download_files, create_request_json, save_file_system 단계는 도달하지 못함
  • 동일 서비스의 다른 job (sitetrack 16707, job 1026390)은 정상 완료

BIM 검증 실패 빈도 확인 쿼리:

text
service:cupixworks-sitetrack-preprocessor-agent "None of the bim mesh_states"

14일간 10건 이상 발생 (2026-04-17 ~ 2026-04-21), 다양한 sitetrack에서 반복됨.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Facility의 BIM 모델이 extracted 상태가 아니거나 published_at이 없어 필터링에서 전부 제외됨 validatesCPBims warn 로그: "None of the bim mesh_states are extracted" (base-preprocessor-runner.ts:59). createCPBims.filter(bim => bim.mesh_state === 'extracted').filter(bim => bim.published_at) 필터 통과 BIM이 0개. 14일간 10건 이상 동일 패턴 반복. Confirmed
H2 BIM API 호출 자체가 실패하여 빈 배열이 반환됨 API 호출 실패 시 createCPBims에서 별도 에러가 throw되며, 로그에 API 에러 흔적 없음. createCPSitetrack까지 정상 완료 로그 확인. Rejected
H3 Sitetrack 16710 자체가 유효하지 않은 상태 `createCPSitetrack end 로그에서 정상 로드 확인. sitetrack API 호출 성공 (preprocessor-service.ts:116`).

Fix Recommendation#

즉시 조치 (Critical)#

  • 없음. 이 에러는 사용자 데이터 상태(BIM mesh 미추출)에 의한 예상 가능한 실패이며, 코드 버그가 아님.

단기 개선 (1주 이내)#

  • preprocessor-service.ts:95에서 validatesCPBims 실패를 error 레벨이 아닌 warn 레벨로 로깅하는 것을 검토. 현재 catch 블록이 모든 예외를 동일하게 logger.error로 처리하므로, BIM 데이터 부재와 같은 예상 가능한 실패와 진짜 시스템 에러를 구분하지 못함.
  • 접근 방법: validatesCPBims에서 reject할 때 커스텀 에러 클래스(예: DataPreconditionError)를 사용하고, catch 블록에서 이 타입이면 logger.warn으로 처리.

장기 개선 (재발 방지)#

  • Preprocessor 파이프라인에서 데이터 전제 조건 미충족(BIM 미추출, Task 미존재 등)과 시스템 에러를 구분하는 에러 분류 체계를 도입. ErrorCode.Agent.DeviationBimMeshNotExtractedState를 이미 설정하고 있으므로, 이를 로그 레벨 결정에도 활용.
  • 사용자가 BIM mesh가 아직 추출되지 않은 상태에서 sitetrack 전처리를 요청하는 패턴이 빈번하다면, 전처리 요청 시점에 BIM 상태를 사전 검증하여 불필요한 job 생성을 방지.

Monitoring#

  • BIM 유효성 검증 실패를 별도 메트릭으로 추적:
text
service:cupixworks-sitetrack-preprocessor-agent "None of the bim mesh_states are extracted"
  • 이 패턴의 빈도가 급증하면 BIM 추출 파이프라인 자체에 문제가 있을 수 있으므로 알림 설정 권장.

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: standard — catch 블록의 에러 분류 로직 추가 필요