FileSystemManager::loadSkatResults | end - failed to load skat results
RCA: FileSystemManager::loadSkatResults | end - failed to load skat results
Error Log#
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.json의 unaligned_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)에서:- EFS에서
capture_alignments.json(sampled skat results) 파일을 로드하고 파싱 - 파싱된
skatResults객체를cpCapture.fromSkatResults(skatResults)에 전달 (line 301)
- EFS에서
// 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)에서:- clusters를 순회하며
CPCluster를 생성 (line 376-384) — 여기서 perspective key 불일치 warn 로그 발생 unaligned_perspectives배열을 순회하며 각 perspective의 key로 capture asset을 조회 (line 413-422)this.getAssetFromKey(skatPerspective.key)가undefined를 반환하면 즉시false반환
- clusters를 순회하며
-
Failure point:
cpcapture.ts:418-421
// 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 keyj3kuJaIbmz를 찾지 못해false를 반환하고 전체 후처리가 실패
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-capture-postprocessor-agent "FileSystemManager::loadSkatResults" @environment:production
service:cupixworks-capture-postprocessor-agent status:error @environment:production
service:cupixworks-capture-postprocessor-agent @capture.id:676105 @environment:production
Capture 676105 — 에러 직전 로그 시퀀스 (verbatim):
[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):
[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):
{"error":"undefined error","sqsMessage":{"MessageId":"126d1eb5-ff1f-4e5e-a26f-81cd0b747fd6","Attributes":{"ApproximateReceiveCount":"1"}}}
[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"로 분류되는 점도 개선 필요 —loadSkatResultsreject 시 적절한 에러 코드(AGT1201)가 전파되도록 에러 핸들링 보강
장기 개선 (재발 방지)#
- Skat SDK 출력과 capture asset 모델 간 데이터 정합성 검증(validation) 레이어 추가 — skat 처리 전/후로 asset 목록 일치 여부를 사전 확인
fromSkatResults메서드에서 엄격한(strict) 모드와 관용적(tolerant) 모드를 구분하여, 부분 실패 시에도 정상 데이터는 처리 가능하도록 설계 변경 검토
Monitoring#
- 추가할 메트릭:
loadSkatResults실패 시 누락된 asset key 수와 전체 perspective 수를 함께 로깅하여 부분 실패 비율 파악 - Datadog 쿼리:
service:cupixworks-capture-postprocessor-agent "not found asset - asset key" @environment:production
service:cupixworks-capture-postprocessor-agent "failed to load skat results" @environment:production
Risk Assessment#
- Risk level: medium
- 예상 복잡도: standard —
fromSkatResults의unaligned_perspectives순회 로직에서return false대신 skip+warn 처리로 변경하는 것은 비교적 단순하나, skat 결과의 데이터 정합성 근본 원인 파악이 필요