ES /docs

FileSystemManager::loadSkatResults | end - failed to load skat results

RCA: FileSystemManager::loadSkatResults | end - failed to load skat results

Error Log#

Datadog Logs

text
FileSystemManager::loadSkatResults | end - failed to load skat results

Impact#

  • Service: cupixworks-capture-postprocessor-agent
  • Team: demokr
  • 발생 횟수: 3
  • 최초 발생: 2026-04-07T05:00:40.814Z
  • 최근 발생: 2026-04-07T05:02:44.125Z

Root Cause Summary#

Skat(Scenemapper) alignment 처리 결과인 capture_alignments.jsonunaligned_perspectives 배열에 포함된 asset key가 capture 모델에 로드된 asset 목록에 존재하지 않아 CPCapture.fromSkatResults()false를 반환하고, 이로 인해 FileSystemManager::loadSkatResults가 reject되어 에러가 발생했습니다. 동일 세션(4e0eec134d8754d1d20a8843668269ca2a3f10d3)의 두 capture(676105, 676113)에서 동일한 패턴으로 3회 발생했으며, 모두 동일 사용자(sean.lee@cupix.com)의 demokr 팀 작업입니다. Skat SDK 자체는 정상 완료(error_code: "")되었으나, skat 결과에 포함된 perspective key가 capture의 asset 모델과 불일치하는 데이터 정합성 문제가 원인입니다.

Technical Analysis#

Code Path#

  • Entry point: PostprocessorService.run() — SQS 메시지를 받아 capture 후처리 파이프라인을 실행

    • postprocessor-service.ts:99에서 fileSystemManager.loadSkatResults(cpCapture)를 호출
  • FileSystemManager::loadSkatResults (file-system.manager.ts:205-310)에서:

    1. EFS에서 capture_alignments.json (sampled skat results) 파일을 로드하고 파싱
    2. 파싱된 skatResults 객체를 cpCapture.fromSkatResults(skatResults)에 전달 (line 301)
typescript
// file-system.manager.ts:301-309
if (cpCapture.fromSkatResults(skatResults)) {
    if (this.setErrorCode) this.setErrorCode(ErrorCode.Agent.Default);
    logger.debug('FileSystemManager::loadSkatResults | end');
    return resolve();
} else {
    logger.error('FileSystemManager::loadSkatResults | end - failed to load skat results');
    return reject();
}
  • CPCapture.fromSkatResults() (cpcapture.ts:349-431)에서:

    1. clusters를 순회하며 CPCluster를 생성 (line 376-384) — 여기서 perspective key 불일치 warn 로그 발생
    2. unaligned_perspectives 배열을 순회하며 각 perspective의 key로 capture asset을 조회 (line 413-422)
    3. this.getAssetFromKey(skatPerspective.key)undefined를 반환하면 즉시 false 반환
  • Failure point: cpcapture.ts:418-421

typescript
// cpcapture.ts:413-422
for (let index = 0; index < skatResults.unaligned_perspectives.length; index++) {
    const skatPerspective = skatResults.unaligned_perspectives[index];
    const cpAsset = this.getAssetFromKey(skatPerspective.key);
    if (cpAsset) {
        cpAsset.fromSkatData(skatPerspective);
    } else {
        logger.warn('CPCapture::fromSkatResult | not found asset - asset key: %s', skatPerspective.key);
        return false;
    }
}
  • 기대 동작: skat 결과의 unaligned_perspectives에 포함된 모든 asset key가 capture 모델의 asset 목록에 존재해야 함
  • 실제 동작: capture 676105에서 asset key Obk9s9ZGEc를, capture 676113에서 asset key j3kuJaIbmz를 찾지 못해 false를 반환하고 전체 후처리가 실패

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-capture-postprocessor-agent "FileSystemManager::loadSkatResults" @environment:production
text
service:cupixworks-capture-postprocessor-agent status:error @environment:production
text
service:cupixworks-capture-postprocessor-agent @capture.id:676105 @environment:production

Capture 676105 — 에러 직전 로그 시퀀스 (verbatim):

text
[2026-04-07T05:00:40.681Z] [info]  CPCapture::fromMeta | key: xXeK8lUQp, version: 1
[2026-04-07T05:00:40.723Z] [info]  CPCapture::fromSkatMasterResults | {"error_code":"","skatsdk_version":{"ver":"3.30.1\tce6d9cf92f211a9d579d8db00421accb34cc1f99\t20260211_081142\tarm64\tUbuntu 22.04.1 LTS"}}
[2026-04-07T05:00:40.782Z] [warn]  FileSystemManager::loadSkatResults | end - not found file - /efs/2ee1101d9871f9d9/skatmaster/results/align_preview_default.png
[2026-04-07T05:00:40.787Z] [warn]  FileSystemManager::loadSkatResults | end - not found file - /efs/2ee1101d9871f9d9/skatmaster/results/align_preview_refinement_with_prior_map.png
[2026-04-07T05:00:40.793Z] [warn]  FileSystemManager::loadSkatResults | end - not found file - /efs/2ee1101d9871f9d9/skatmaster/results/align_preview_meta_refinement_with_prior_map.json
[2026-04-07T05:00:40.798Z] [warn]  FileSystemManager::loadSkatResults | end - not found file - /efs/2ee1101d9871f9d9/skatmaster/results/align_preview_meta_default.json
[2026-04-07T05:00:40.811Z] [info]  FileSystemManager::loadSkatResults | read file meta - created at: Tue Apr  7 04:56:30 2026 GMT, skatSDK: 3.30.1
[2026-04-07T05:00:40.813Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: r41KZ2-fMR, skatPerspectiveName: DJI_20251029173918_0291_V.JPG
[2026-04-07T05:00:40.813Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: MjUTSqk86u, skatPerspectiveName: DJI_20251029173920_0292_V.JPG
[2026-04-07T05:00:40.814Z] [warn]  CPCapture::fromSkatResult | not found asset - asset key: Obk9s9ZGEc
[2026-04-07T05:00:40.814Z] [error] FileSystemManager::loadSkatResults | end - failed to load skat results

Capture 676113 — 에러 직전 로그 시퀀스 (verbatim):

text
[2026-04-07T05:02:44.017Z] [info]  CPCapture::fromMeta | key: hMJ6LP82Z, version: 1
[2026-04-07T05:02:44.046Z] [info]  CPCapture::fromSkatMasterResults | {"error_code":"","skatsdk_version":{"ver":"3.30.1..."}}
[2026-04-07T05:02:44.118Z] [info]  FileSystemManager::loadSkatResults | read file meta - created at: Tue Apr  7 05:02:29 2026 GMT, skatSDK: 3.30.1
[2026-04-07T05:02:44.120Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: mTA7CgVUhd, skatPerspectiveName: DJI_20251022112856_0229_V.JPG
[2026-04-07T05:02:44.122Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: ygAhAXsOXo, skatPerspectiveName: DJI_20251022112857_0230_V.JPG
[2026-04-07T05:02:44.123Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: tdfQAzhlWxO, skatPerspectiveName: DJI_20251022113411_0331_V.JPG
[2026-04-07T05:02:44.123Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: 7_YKkleZHJ9, skatPerspectiveName: DJI_20251022113413_0332_V.JPG
[2026-04-07T05:02:44.124Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: 8KnbCPpa6Z, skatPerspectiveName: DJI_20251022113923_0404_V.JPG
[2026-04-07T05:02:44.124Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: xhfw9i6CxrD, skatPerspectiveName: DJI_20251022113917_0401_V.JPG
[2026-04-07T05:02:44.124Z] [warn]  CPCluster::fromSkatData | not found skatPerspectiveKey: 5-nnjgOvvq, skatPerspectiveName: DJI_20251022114050_0427_V.JPG
[2026-04-07T05:02:44.125Z] [warn]  CPCapture::fromSkatResult | not found asset - asset key: j3kuJaIbmz
[2026-04-07T05:02:44.125Z] [error] FileSystemManager::loadSkatResults | end - failed to load skat results

에러 후속 처리 (capture 676105):

json
{"error":"undefined error","sqsMessage":{"MessageId":"126d1eb5-ff1f-4e5e-a26f-81cd0b747fd6","Attributes":{"ApproximateReceiveCount":"1"}}}
text
[2026-04-07T05:00:43.215Z] [warn]  JobManager::updateErrorActionJob | end - {name: 'HttpError', message: 'HTTP request failed', ...}

타임라인 정리:

시간 (UTC) 이벤트 Capture
04:56:30 Skat SDK 처리 완료 (capture_alignments.json 생성) 676105
05:00:40.681 Postprocessor agent가 capture 676105 처리 시작 676105
05:00:40.814 fromSkatResults 실패 — asset key Obk9s9ZGEc 미발견 (1차) 676105
05:00:42.997 동일 capture 재처리 실패 (2차) 676105
05:02:29 Skat SDK 처리 완료 (capture_alignments.json 생성) 676113
05:02:44.125 fromSkatResults 실패 — asset key j3kuJaIbmz 미발견 676113

공통 패턴:

  • 두 capture 모두 동일 세션 4e0eec134d8754d1d20a8843668269ca2a3f10d3에 속함
  • 모든 누락된 perspective 파일명이 DJI_*_V.JPG 패턴 — DJI 드론의 수직(Vertical) 촬영 이미지
  • Skat SDK(3.30.1)는 error_code: ""로 정상 완료되었으나, 결과에 포함된 perspective key가 postprocessor의 capture asset 모델에 없음

Fix Recommendation#

즉시 조치 (Critical)#

  • 파일: cpcapture.ts:418-421
  • unaligned_perspectives에서 매칭되지 않는 asset key가 발견되었을 때 즉시 return false로 전체 후처리를 실패시키는 대신, 해당 perspective를 skip하고 경고만 남기는 방식으로 변경 검토
  • 현재 동작은 하나의 누락 asset으로 인해 전체 capture 후처리가 실패하여 모든 정상 alignment 데이터까지 버려지는 문제가 있음
  • 동일한 패턴이 CPCluster::fromSkatData의 perspective key 불일치(warn 로그)에서도 관찰되나, cluster 처리에서는 warn만 남기고 계속 진행함 — unaligned_perspectives 처리도 동일한 관용적 처리(tolerant handling)를 적용하는 것이 일관적

단기 개선 (1주 이내)#

  • Skat SDK 결과(capture_alignments.json)에 포함되는 perspective key가 어떤 기준으로 생성되는지 확인 필요 — capture의 preprocessor 단계에서 등록된 asset 목록과 skat SDK가 처리하는 입력 파일 목록 간의 불일치가 근본 원인일 가능성
  • DJI 드론의 _V.JPG(수직 촬영) 이미지가 capture asset으로 등록되지 않거나, skat SDK가 해당 이미지를 별도 perspective로 인식하는 과정에서 key 매핑이 어긋나는 시나리오를 조사
  • BaseService::getApiErrorToDeleteMessage에서 "undefined error"로 분류되는 점도 개선 필요 — loadSkatResults reject 시 적절한 에러 코드(AGT1201)가 전파되도록 에러 핸들링 보강

장기 개선 (재발 방지)#

  • Skat SDK 출력과 capture asset 모델 간 데이터 정합성 검증(validation) 레이어 추가 — skat 처리 전/후로 asset 목록 일치 여부를 사전 확인
  • fromSkatResults 메서드에서 엄격한(strict) 모드와 관용적(tolerant) 모드를 구분하여, 부분 실패 시에도 정상 데이터는 처리 가능하도록 설계 변경 검토

Monitoring#

  • 추가할 메트릭: loadSkatResults 실패 시 누락된 asset key 수와 전체 perspective 수를 함께 로깅하여 부분 실패 비율 파악
  • Datadog 쿼리:
text
service:cupixworks-capture-postprocessor-agent "not found asset - asset key" @environment:production
text
service:cupixworks-capture-postprocessor-agent "failed to load skat results" @environment:production

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: standard — fromSkatResultsunaligned_perspectives 순회 로직에서 return false 대신 skip+warn 처리로 변경하는 것은 비교적 단순하나, skat 결과의 데이터 정합성 근본 원인 파악이 필요