RefinementService::checkInputFiles | not found alignment_archive.bin
RCA: RefinementService::checkInputFiles | not found alignment_archive.bin
Error Log#
RefinementService::checkInputFiles | not found alignment_archive.bin
Impact#
- Service:
cupixworks-capture-refinement-arm-instance - Team: pclconstruction
- 발생 횟수: 2
- 최초 발생: 2026-04-09T00:53:27.381Z
- 최근 발생: 2026-04-09T02:26:07.874Z
Root Cause Summary#
Refinement agent가 실행 시 EFS 경로(EFS_SKATMASTER_PATH/results/alignment_archive.bin)에서 alignment_archive.bin 파일을 찾지 못해 실패했습니다. 이 파일은 upstream 프로세스인 cupix-skat-master-agent의 copyAlignPreviewFilesToSkatMasterResult 메서드가 scenemapper 처리 결과를 EFS에 복사할 때 생성됩니다. 2건의 에러 모두 RefinementService::run | begin 직후 checkInputFiles에서 즉시 실패하는 패턴을 보이며, upstream skat-master 처리 단계에서 alignment_archive.bin 파일이 생성되지 않았거나, EFS에 정상 복사되지 않은 상태에서 refinement job이 트리거된 것이 원인입니다.
Technical Analysis#
Code Path#
- Entry point:
refinement-service.ts:43—init()호출로 인증 후run()실행 run()메서드:refinement-service.ts:79-111— job 로드 후checkInputFiles()호출- Failure point:
refinement-service.ts:144-154—checkInputFiles()에서alignment_archive.bin존재 여부 확인
checkInputFiles는 run() 메서드에서 job 로드 및 cpCapture 생성 직후, 모든 비즈니스 로직보다 먼저 호출됩니다:
// refinement-service.ts:79-111
private run = async (): Promise<void> => {
logger.info('RefinementService::run | begin');
try {
const srvJob = await this.jobManager.loadJob(Environment.CPX_JOB_ID as number);
await this.jobManager.updateRunningActionJob('refinement');
const cpCapture = srvJob ? await this.createCPCaptureByJob(srvJob) : undefined;
if (cpCapture) {
this.checkInputFiles(); // ← 여기서 실패
await this.loadEntityParameter(cpCapture);
// ... 이후 로직 실행되지 않음
}
// ...
} catch (error) {
logger.error('RefinementService::run | end - %s', JSON.stringify(error));
await this.jobManager.updateErrorActionJob('refinement');
}
};
checkInputFiles 메서드는 EFS_SKATMASTER_PATH/results/alignment_archive.bin 경로에 파일이 존재하는지 fs.existsSync로 확인합니다:
// refinement-service.ts:144-154
private checkInputFiles = () => {
logger.debug('RefinementService::checkInputFiles | begin');
const skatMasterEfsPath = path.join(Environment.EFS_SKATMASTER_PATH, Constants.DefaultResultsDirName);
const binFileEfsPath = path.join(skatMasterEfsPath, Constants.DefaultAlignPreviewBinFileName);
if (!fs.existsSync(binFileEfsPath)) {
logger.error('RefinementService::checkInputFiles | not found alignment_archive.bin');
this.jobManager.setErrorCode(ErrorCode.ScenemapperUtils.RefinerExpiredInputFiles);
throw new Error('not found alignment_archive.bin');
}
logger.debug('RefinementService::checkInputFiles | end');
};
여기서 DefaultResultsDirName은 results이고 DefaultAlignPreviewBinFileName은 alignment_archive.bin입니다 (shared-config constants.ts:23, refinement constants constants.ts:26).
이 파일을 EFS에 생성하는 upstream 코드는 cupix-skat-master-agent의 copyAlignPreviewFilesToSkatMasterResult 메서드입니다:
// cupix-skat-master-agent/src/manager/skatmaster.manager.ts:507-508
const binFilePath = path.join(this.resultDirPath, Constants.DefaultAlignPreviewBinFileName);
this.efsManager.copyTo(binFilePath, path.join(this.efsManager.skatMasterResultPath, Constants.DefaultAlignPreviewBinFileName));
skat-master가 scenemapper 실행 결과에서 alignment_archive.bin을 로컬 결과 디렉토리에 생성하고 이를 EFS에 복사하는 구조입니다. skat-master에서 이 파일이 생성되지 않았거나 EFS 복사가 실패하면, 이후 트리거되는 refinement agent에서 checkInputFiles 단계에서 즉시 실패합니다.
또한, cupix-capture-postprocessor-agent의 PreparationRefinementService::checkRefinementResult (preparation-refinement-service.ts:36-69)도 동일 파일 존재를 확인하지만, 파일이 없으면 refinement 상태를 ready로 전환하지 않는 soft-fail 방식입니다. 이 두 에러 케이스에서는 postprocessor의 체크를 우회하거나, postprocessor가 파일 존재를 확인한 이후 EFS에서 파일이 삭제/만료된 것으로 판단됩니다.
Log Evidence#
첫 번째 발생 (09:53:27 KST):
Datadog query: service:cupixworks-capture-refinement-arm-instance (status:error OR status:info OR status:warn) "RefinementService" from:2026-04-09T00:53:00Z to:2026-04-09T00:53:40Z
09:53:27 KST [info] RefinementService::init
09:53:27 KST [info] RefinementService::authenticate | begin
09:53:27 KST [info] RefinementService::authenticate | end
09:53:27 KST [info] RefinementService::run | begin
09:53:27 KST [error] RefinementService::checkInputFiles | not found alignment_archive.bin
09:53:27 KST [error] RefinementService::run | end - {}
09:53:28 KST [info] RefinementService::terminateService | force shutdown after 10 seconds
두 번째 발생 (11:26:07 KST):
Datadog query: service:cupixworks-capture-refinement-arm-instance (status:error OR status:info OR status:warn) "RefinementService" from:2026-04-09T02:25:30Z to:2026-04-09T02:26:30Z
11:26:07 KST [info] RefinementService::authenticate | begin
11:26:07 KST [info] RefinementService::init
11:26:07 KST [info] RefinementService::authenticate | end
11:26:07 KST [info] RefinementService::run | begin
11:26:07 KST [error] RefinementService::checkInputFiles | not found alignment_archive.bin
11:26:07 KST [error] RefinementService::run | end - {}
11:26:08 KST [info] RefinementService::terminateService | force shutdown after 10 seconds
양쪽 모두 동일한 패턴: init → authenticate → run | begin → checkInputFiles | not found → run | end - {} → terminateService. run | begin에서 checkInputFiles까지 1초 이내로, job 로드 후 즉시 파일 존재 체크에서 실패합니다.
추가로, 같은 시간대에 다수의 RefinementService::run | end - {} 에러가 관찰되었으며 (다른 인스턴스에서), 일부는 copyAlignmentToEfs | not found refined align_preview_meta_refinement_with_prior_map.json 워닝과 함께 발생했습니다. 이는 refinement 실행 자체가 결과를 생성하지 못한 별도 케이스입니다.
Fix Recommendation#
즉시 조치 (Critical)#
refinement-service.ts:107-110의 에러 핸들러에서JSON.stringify(error)가{}를 출력합니다.Error객체를JSON.stringify하면 빈 객체가 됩니다.error instanceof Error ? error.message : JSON.stringify(error)또는error.message || error로 변경하여 에러 메시지가 로그에 포함되도록 해야 합니다.- 동일 이슈가
refinement-service.ts:75의authenticate에러 핸들러에도 존재합니다.
단기 개선 (1주 이내)#
checkInputFiles에서 실패할 때 에러 코드RefinerExpiredInputFiles를 설정하지만, 로그에EFS_SKATMASTER_PATH경로 값을 출력하지 않아 디버깅이 어렵습니다. 확인하려는 파일의 전체 경로(binFileEfsPath)를 에러 로그에 포함하도록 개선이 필요합니다.- Upstream
cupix-skat-master-agent에서copyAlignPreviewFilesToSkatMasterResult실행 시 파일 복사 성공/실패를 명확하게 로깅하고, 실패 시 후속 refinement job을 트리거하지 않도록 guard 조건을 강화해야 합니다. 현재skatmaster.manager.ts:514-517에서 예외 발생 시return false만 하고 warning 로그만 남기는데, 이 반환값이 refinement 트리거 여부에 정확히 반영되는지 검증이 필요합니다.
장기 개선 (재발 방지)#
- Refinement agent 시작 전에 필수 input 파일의 존재를 검증하는 pre-flight check를 job 스케줄링 단계에서 수행하도록 아키텍처 변경. 현재는 ECS task가 시작된 후에야 파일 부재를 감지하므로, 불필요한 인프라 비용이 발생합니다.
- EFS 파일의 생명주기 관리 (TTL, cleanup policy)가 있다면, refinement job 스케줄링 시점과의 타이밍 이슈를 점검.
RefinerExpiredInputFiles라는 에러 코드명이 이미 "만료된 입력 파일"을 의미하므로, EFS 파일 정리 정책과 job 큐 지연 사이의 race condition 가능성이 있습니다.
Monitoring#
alignment_archive.bin누락 에러 빈도를 추적하는 모니터:
service:cupixworks-capture-refinement-arm-instance "checkInputFiles" "not found alignment_archive.bin" status:error
- Upstream skat-master의
copyAlignPreviewFilesToSkatMasterResult실패율 모니터:
service:cupixworks-capture-skatmaster* "copyAlignPreviewFilesToSkatMasterResult" "exception occurred"
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 발생 빈도가 낮고 (2건), 자동 에러 처리 후 terminateService로 정상 종료됩니다. 사용자 데이터 손실 없이 refinement가 실패 상태로 마킹되므로 재시도 가능합니다. 다만 에러 로그가
{}로 출력되어 디버깅에 불편함이 있으므로, 로그 개선은 즉시 수행하는 것이 좋습니다.