ES /docs

FileSystemManager::loadSkatResults | end - not found file - /efs/a0504a63e1595b88/skatmaster/results

RCA: FileSystemManager::loadSkatResults — capture_alignments.json not found

Overview#

What Happened#

2026-04-22 13:17~13:20 UTC 사이 cupixworks-capture-postprocessor-agent에서 5건의 에러가 발생했다. postprocessor agent가 EFS 상의 skatmaster/results/capture_alignments.json 파일을 읽으려 했으나 파일이 존재하지 않아 처리에 실패했다. 5건은 3개 팀(lemartec, futsu, whitingturner/rsconstruction), 2개 리전(us-west-2, ap-southeast-1)에 걸쳐 서로 다른 capture에서 발생했으며, 각 실패 후 BaseService::handlingMessageErrors에 의해 SQS 메시지가 에러 처리되었다. 대표 에러인 capture 683964의 경우, upstream에서 이미 에러 코드 AGT1201이 설정되어 있었고 SKAT이 alignment 결과를 생성하지 않았음에도 postprocessor가 트리거되었다.

Quick Facts#

Field Value
exception.message FileSystemManager::loadSkatResults | end - not found file - /efs/{hash}/skatmaster/results/capture_alignments.json
top_frame packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:229
env production, us-west-2, ap-southeast-1

Affected Teams#

Team / Domain Error Count Impact
lemartec 1 capture 683964 postprocessing 실패 (error code AGT1201)
futsu 1 capture 1782 postprocessing 실패 (ap-southeast-1)
whitingturner 2 capture 684676, 684675 postprocessing 실패
rsconstruction 1 capture 684637 postprocessing 실패

Timeline#

  1. 2026-04-22T13:17:15Z — 최초 에러 발생 (EFS path: a0504a63e1595b88)
  2. 2026-04-22T13:18:45Z — 두 번째 에러 (EFS path: 5ddfd1ddad055ad5)
  3. 2026-04-22T13:20:20-25Z — 세 건 연속 에러 (EFS paths: 8dd318811e13d33c, baf3b2c7b31bb1c2, 414cc7a32da9f924)
  4. 2026-04-22T13:43~Z — 동일 시간대의 다른 capture들은 loadSkatResults 성공 (info 로그 확인)

Error Log#

Datadog Logs

text
FileSystemManager::loadSkatResults | end - not found file - /efs/a0504a63e1595b88/skatmaster/results/capture_alignments.json

Impact#

  • Service: cupixworks-capture-postprocessor-agent
  • Team: lemartec
  • 발생 횟수: 5
  • 최초 발생: 2026-04-22T13:17:15.928Z
  • 최근 발생: 2026-04-22T13:20:25.336Z

Root Cause Summary#

Postprocessor agent가 capture_alignments.json이 EFS에 존재하지 않는 상태에서 SQS 메시지를 받아 처리를 시작했다. 대표 에러(capture 683964)의 cross-service 로그 분석 결과, 해당 capture는 이미 upstream에서 에러 코드 AGT1201이 설정되어 있었으며 "3D reconstruction was skipped due to the existence of an capture error code"라는 로그가 확인된다. 즉, skatmaster가 alignment 결과를 생성하지 않았음에도 postprocessor가 트리거된 것이다. Postprocessor의 run() 메서드(line 91-99)는 loadSkatMasterResults()processing_status.json을 먼저 로드하고, cpCapture.errorCode 체크(line 92)를 통과한 후 loadSkatResults()에서 capture_alignments.json을 읽는다. 그러나 skatmaster가 에러로 인해 alignment 계산을 건너뛴 경우, processing_status.json은 존재하되 capture_alignments.json은 미생성 상태이므로 여기서 실패한다. 이는 upstream 에러 상태의 capture에 대해 postprocessor가 불필요하게 트리거되는 문제와, processing_status.json 내 에러 상태를 loadSkatResults 호출 전에 충분히 검증하지 못하는 문제의 복합이다.

Technical Analysis#

Code Path#

  • Entry point: postprocessor-service.ts:64run() 메서드가 SQS 메시지로부터 호출
  • postprocessor-service.ts:87fileSystemManager.setEfsPath(cpCapture) — capture의 EFS 경로 설정
  • postprocessor-service.ts:91fileSystemManager.loadSkatMasterResults(cpCapture)processing_status.json 로드 (성공)
  • postprocessor-service.ts:99fileSystemManager.loadSkatResults(cpCapture, this.actionName) — alignment 결과 로드 시도
  • Failure point: file-system.manager.ts:228-230capture_alignments.json 파일 존재 여부 확인 후 에러 로그 출력 및 reject
packages/cupix-capture-postprocessor-agent/src/postprocessor-service.ts:85-99typescript
const fileSystemManager = new FileSystemManager(Environment.DEBUG_MODE);
fileSystemManager.setErrorCode = (errorCode: string) => this.jobManager.setErrorCode(errorCode);
fileSystemManager.setEfsPath(cpCapture);
fileSystemManager.makeEfsDirectory();
await fileSystemManager.loadCPCaptureModel(cpCapture);
await fileSystemManager.loadCPCaptureModelFromVideoDecodingResult(cpCapture);
await fileSystemManager.loadSkatMasterResults(cpCapture);
if (cpCapture.errorCode !== '') {
    this.jobManager.setErrorCode(cpCapture.errorCode);
    const msg = `PostprocessorService::run - found skat-master error code - ${cpCapture.errorCode}`;
    logger.error(msg);
    throw new Error(msg);
}

await fileSystemManager.loadSkatResults(cpCapture, this.actionName);

loadSkatResults 내부에서 capture_alignments.json (DefaultSkatSampledJsonFileName)은 필수 파일로 취급되며, 파일이 없으면 즉시 reject된다:

packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:226-231typescript
// Sampled Results
const skatSampledResultsFilePath = path.join(this.skatMasterDirPath, Constants.DefaultResultsDirName, Constants.DefaultSkatMasterFileName);
if (CPUtils.getFileSize(skatSampledResultsFilePath) === -1) {
    logger.error('FileSystemManager::loadSkatResults | end - not found file - %s', skatSampledResultsFilePath);
    return reject();
}

상수 정의에서 DefaultSkatSampledJsonFileName = 'capture_alignments.json' (constants.ts:21)으로, 이 파일은 SKAT alignment 계산의 최종 output이다.

기대 동작: SKAT 처리가 완전히 완료된 후 postprocessor가 트리거되어 모든 결과 파일이 EFS에 준비된 상태에서 읽힘. 실제 동작: SKAT 처리 중간(processing_status.json은 존재하지만 capture_alignments.json은 아직 미생성) 시점에 postprocessor가 트리거됨.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-capture-postprocessor-agent status:error "loadSkatResults"
Time: 2026-04-22T12:17:00Z ~ 2026-04-22T13:50:00Z

5건의 에러 로그 — 모두 서로 다른 EFS 경로에서 동일 패턴 발생:

text
2026-04-22 22:17:15 KST | error | FileSystemManager::loadSkatResults | end - not found file - /efs/a0504a63e1595b88/skatmaster/results/capture_alignments.json
2026-04-22 22:18:45 KST | error | FileSystemManager::loadSkatResults | end - not found file - /efs/5ddfd1ddad055ad5/skatmaster/results/capture_alignments.json
2026-04-22 22:20:20 KST | error | FileSystemManager::loadSkatResults | end - not found file - /efs/8dd318811e13d33c/skatmaster/results/capture_alignments.json
2026-04-22 22:20:23 KST | error | FileSystemManager::loadSkatResults | end - not found file - /efs/baf3b2c7b31bb1c2/skatmaster/results/capture_alignments.json
2026-04-22 22:20:25 KST | error | FileSystemManager::loadSkatResults | end - not found file - /efs/414cc7a32da9f924/skatmaster/results/capture_alignments.json

각 에러 직후 BaseService::handlingMessageErrors 로그가 "undefined error"로 기록됨:

text
2026-04-22 22:17:17 KST | error | BaseService::handlingMessageErrors | Error and message object - {"error":"undefined error","sqsMessage":{"MessageId":"2c76eed8-3419-4544-8d9a-b2a77fd2e03d","Attributes":{"ApproximateReceiveCount":"1"}}}

동일 시간대의 다른 capture들은 약 25분 후 성공:

text
service:cupixworks-capture-postprocessor-agent status:info "loadSkatResults"
text
2026-04-22 22:43:23 KST | info | FileSystemManager::loadSkatResults | read file meta - created at: Wed Apr 22 13:37:54 2026 GMT, skatSDK: 3.30.4
2026-04-22 22:44:36 KST | info | FileSystemManager::loadSkatResults | read file meta - created at: Wed Apr 22 13:32:27 2026 GMT, skatSDK: 3.30.4

성공한 capture들의 capture_alignments.jsoncreated 필드는 13:3213:39 UTC로, 에러 발생 시점(13:1713:20)보다 이후이다. 이는 에러 발생 시점에 SKAT alignment 계산이 아직 진행 중이었음을 확인시켜준다.

"skat-master error code" 검색 결과 0건이므로, loadSkatMasterResults() (processing_status.json)는 모든 케이스에서 성공적으로 로드되었다. 그러나 processing_status.json 로드 성공이 alignment 결과 존재를 보장하지는 않는다.

Cross-service 로그 (capture 683964 관련):

text
"683964" (all services)
Time: 2026-04-22T13:17:00Z ~ 2026-04-22T13:18:00Z
text
2026-04-22 13:17:15.268Z | info  | BaseService::runByMessage | id: 1024816
2026-04-22 13:17:15.315Z | info  | JobManager::loadJob | begin - job id: 1024816
2026-04-22 13:17:15.357Z | info  | JobManager::loadJob | end - job id: 1024816
2026-04-22 13:17:15.928Z | error | FileSystemManager::loadSkatResults | end - not found file - .../capture_alignments.json
2026-04-22 13:17:17.061Z | info  | create editing entity on Capture 683964
2026-04-22 13:17:17.062Z | info  | Analysis skipped: error_code=AGT1201. capture_id: 683964
2026-04-22 13:17:17.062Z | info  | 3D reconstruction was skipped due to the existence of an capture error code. capture_id: 683964, error_code: AGT1201
2026-04-22 13:17:17.062Z | info  | capture 683964 publish skipped: error_code(AGT1201) exist

이 로그는 capture 683964가 이미 에러 상태(AGT1201)였음을 확인한다. Skatmaster가 해당 capture에 대해 alignment 계산을 실행하지 않았기 때문에 capture_alignments.json이 EFS에 생성되지 않았다. 그럼에도 postprocessor SQS 메시지가 전달되어 처리가 시도되었다.

5건의 에러에 대한 상세 정보:

Timestamp (UTC) EFS Path Capture ID Job ID Team Region
13:17:15 a0504a63e1595b88 683964 1024816 lemartec us-west-2
13:18:45 5ddfd1ddad055ad5 1782 6453 futsu ap-southeast-1
13:20:20 8dd318811e13d33c 684676 1027060 whitingturner us-west-2
13:20:23 baf3b2c7b31bb1c2 684637 1027012 rsconstruction us-west-2
13:20:25 414cc7a32da9f924 684675 1027056 whitingturner us-west-2

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Upstream 에러 상태(AGT1201)의 capture에 대해 postprocessor가 불필요하게 트리거됨 capture 683964의 cross-service 로그: "Analysis skipped: error_code=AGT1201", "3D reconstruction was skipped" — skatmaster가 alignment을 생성하지 않음 나머지 4건의 capture에 대해서는 AGT1201 여부 미확인 (로그 부재) Confirmed (대표 에러)
H2 SKAT 처리 완료 전 postprocessor 조기 트리거 (race condition) 동일 시간대 성공한 capture들의 파일 created 시각(13:32-13:39)이 에러 시점(13:17-13:20)보다 이후, processing_status.json은 존재함 capture 683964는 AGT1201로 인해 alignment 자체가 미실행 — 단순 타이밍 문제가 아닌 에러 상태 문제 Confirmed (일부 케이스)
H3 EFS mount 문제로 파일 접근 불가 같은 EFS 상의 processing_status.json은 정상 로드됨, 5건 모두 서로 다른 EFS 경로이므로 단일 mount 문제 아님 Rejected
H4 SQS 메시지 중복 또는 순서 문제 모든 에러의 ApproximateReceiveCount가 "1"로 첫 번째 수신 Rejected

Fix Recommendation#

즉시 조치 (Critical)#

  • postprocessor-service.ts:92cpCapture.errorCode 체크 이후에도 loadSkatResults 호출 전에 capture의 upstream 에러 상태(예: AGT1201)를 추가 검증하는 guard 추가. Capture가 이미 에러 상태이면 alignment 로드를 건너뛰고 에러 처리 경로로 이동하도록 변경.
  • file-system.manager.ts:229 — 에러 로그 레벨을 warn으로 하향 검토. Upstream 에러로 인한 파일 부재는 시스템 버그가 아닌 expected failure이므로 error가 과도할 수 있음.

단기 개선 (1주 이내)#

  • loadSkatMasterResults에서 로드한 processing_status.json의 내용을 검사하여, SKAT 처리가 alignment 단계까지 도달했는지 확인하는 readiness check 추가. 에러 상태로 종료된 경우 loadSkatResults 호출을 skip.
  • Upstream에서 에러 코드가 있는 capture에 대해 postprocessor SQS 메시지 전송을 억제하는 방안 검토.

장기 개선 (재발 방지)#

  • SKAT 처리 완료 상태를 명확히 구분하는 마커 파일 또는 processing_status.json 내 phase 필드를 활용하여, postprocessor가 각 결과 파일의 존재 여부를 사전에 판단할 수 있도록 프로토콜 정립.
  • Upstream 시스템(SKAT/scenemapper)에서 postprocessor SQS 메시지 전송 시점을 모든 결과 파일 write 완료 이후로 보장하거나, 에러 시 postprocessor 트리거를 하지 않도록 조율.

Monitoring#

  • 추가할 메트릭: capture_alignments.json 파일 누락 빈도 추적
  • Datadog 쿼리:
text
service:cupixworks-capture-postprocessor-agent "loadSkatResults | end - not found file"
  • 파일 미발견 에러가 SQS 재처리 후 성공하는 비율을 모니터링하여, 단순 타이밍 문제인지 영구적 실패인지 구분

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: standard — retry 로직 추가 또는 로그 레벨 변경은 비교적 간단하나, upstream 타이밍 보장은 cross-service 조율 필요