ES /docs

RefinementService::checkInputFiles | not found alignment_archive.bin

RCA: RefinementService::checkInputFiles | not found alignment_archive.bin

Error Log#

Datadog Logs

text
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-agentcopyAlignPreviewFilesToSkatMasterResult 메서드가 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:43init() 호출로 인증 후 run() 실행
  • run() 메서드: refinement-service.ts:79-111 — job 로드 후 checkInputFiles() 호출
  • Failure point: refinement-service.ts:144-154checkInputFiles()에서 alignment_archive.bin 존재 여부 확인

checkInputFilesrun() 메서드에서 job 로드 및 cpCapture 생성 직후, 모든 비즈니스 로직보다 먼저 호출됩니다:

typescript
// 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로 확인합니다:

typescript
// 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');
};

여기서 DefaultResultsDirNameresults이고 DefaultAlignPreviewBinFileNamealignment_archive.bin입니다 (shared-config constants.ts:23, refinement constants constants.ts:26).

이 파일을 EFS에 생성하는 upstream 코드는 cupix-skat-master-agentcopyAlignPreviewFilesToSkatMasterResult 메서드입니다:

typescript
// 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-agentPreparationRefinementService::checkRefinementResult (preparation-refinement-service.ts:36-69)도 동일 파일 존재를 확인하지만, 파일이 없으면 refinement 상태를 ready로 전환하지 않는 soft-fail 방식입니다. 이 두 에러 케이스에서는 postprocessor의 체크를 우회하거나, postprocessor가 파일 존재를 확인한 이후 EFS에서 파일이 삭제/만료된 것으로 판단됩니다.

Log Evidence#

첫 번째 발생 (09:53:27 KST):

text
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
text
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):

text
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
text
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

양쪽 모두 동일한 패턴: initauthenticaterun | begincheckInputFiles | not foundrun | 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:75authenticate 에러 핸들러에도 존재합니다.

단기 개선 (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 누락 에러 빈도를 추적하는 모니터:
text
service:cupixworks-capture-refinement-arm-instance "checkInputFiles" "not found alignment_archive.bin" status:error
  • Upstream skat-master의 copyAlignPreviewFilesToSkatMasterResult 실패율 모니터:
text
service:cupixworks-capture-skatmaster* "copyAlignPreviewFilesToSkatMasterResult" "exception occurred"

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: standard
  • 발생 빈도가 낮고 (2건), 자동 에러 처리 후 terminateService로 정상 종료됩니다. 사용자 데이터 손실 없이 refinement가 실패 상태로 마킹되므로 재시도 가능합니다. 다만 에러 로그가 {}로 출력되어 디버깅에 불편함이 있으므로, 로그 개선은 즉시 수행하는 것이 좋습니다.