ES /docs

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

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

Overview#

What Happened#

2026-07-14 00:05:57 KST 에 cupixworks-capture-postprocessor-agent 가 capture 733859 (workspace /tmp/workspace/733859, skatmaster dir /efs/c39ff4904e0a9f25) 의 skat 결과 파일(capture_alignments.json) 을 로드하다 실패했다. 파일은 존재했으나 내부 unaligned_perspectives[].key = "XlrXyIHkUzO" 가 Tesla API 응답의 cpAssets 목록에서 조회되지 않아 CPCapture.fromSkatResultsfalse 를 반환했고, FileSystemManager::loadSkatResults 가 reject 되었다. SQS 메시지 1건이 실패로 처리되었고 (ApproximateReceiveCount:1), 후속 pipeline(loadStopPanoResults, uploadAlignmentData, updateSkatInfo, _finalizationService) 이 실행되지 않았다.

Quick Facts#

Field Value
exception.class Error (thrown from FileSystemManager.loadSkatResults)
exception.message loadSkatResults: failed to load skat results
top_frame packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:307
runtime Node.js (bundled at /tmp/agent/dist/app.cjs:9063)
env production, us-west-2

Affected Teams#

Team / Domain Error Count Impact
cadscans (capture postprocessing) 1 (1시간 내) / 3 (7일 내) 단일 capture 의 postprocessing 실패. SQS message deleted (재시도 없음), capture 는 postprocess 미완료 상태로 방치됨.

Timeline#

  1. 2026-07-13 23:58:34 KST — skatmaster 가 이전 capture (/efs/9c4103bbb0e54f16) 의 결과 생성 (참고용 시각)
  2. 2026-07-14 00:05:35 KST — skatmaster 가 문제 capture 의 capture_alignments.json 생성 (로그: read file meta - created at: Mon Jul 13 15:05:35 2026 GMT)
  3. 2026-07-14 00:05:56 KSTBaseService::runByMessage | id: 1192118 — 문제 job 소비 시작
  4. 2026-07-14 00:05:57 KSTCPCapture::fromMeta | key: 2jdyiKKRo, version: 1 — capture data 로드
  5. 2026-07-14 00:05:57 KSTCPCapture::fromSkatResult | not found asset - asset key: XlrXyIHkUzO (warn)
  6. 2026-07-14 00:05:57 KSTFileSystemManager::loadSkatResults | end - failed to load skat results (error)
  7. 2026-07-14 00:05:57 KST — SQS message e2f71bfc-de00-4b47-8300-16f4488078ef 삭제 (재시도 없이 dead)
  8. 2026-07-14 00:05:58 KSTBaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/733859 — workspace 정리

Error Log#

Datadog Logs

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

Impact#

  • Service: cupixworks-capture-postprocessor-agent
  • Team: cadscans
  • 발생 횟수: 1 (14일 내 동일 메시지 3건 — 2026-07-07 17:04:53 KST, 2026-07-07 17:29:42 KST, 2026-07-14 00:05:57 KST)
  • 최초 발생: 2026-07-14 00:05:57 KST
  • 최근 발생: 2026-07-14 00:05:57 KST

Root Cause Summary#

Skatmaster (SLAM 정렬 파이프라인) 가 생산한 capture_alignments.jsonunaligned_perspectives 배열에 asset key XlrXyIHkUzO 가 포함되어 있었으나, 같은 capture 를 Tesla API 로 조회했을 때 반환된 TESLA.Capture.assets 목록에는 해당 key 가 없었다. CPCapture.fromSkatResults (cpcapture.ts:415-421) 가 getAssetFromKey(skatPerspective.key) 에서 undefined 를 받고 return false — 이로 인해 FileSystemManager.loadSkatResults (file-system.manager.ts:301-309) 가 error 로 reject 되었다. 즉, upstream skatmaster 산출물과 Tesla capture 메타(현재 서버 상태) 간의 asset 목록 불일치가 원인이다. 세 번의 발생 모두 다른 capture (asset key 도 다름) 에서 나타난 산발적 데이터 스큐로, 단일 capture 처리 실패이지 서비스 광역 장애는 아니다.

Technical Analysis#

Code Path#

  • Entry point: packages/cupix-capture-postprocessor-agent/src/postprocessor-service.ts:99PostprocessorService.runfileSystemManager.loadSkatResults(cpCapture, this.actionName) 호출
  • packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:205-310loadSkatResults 는 다음 순서로 수행
    1. capture_alignments.json (skatSampled) 존재 확인 → 존재해야 함, 아니면 line 229 에서 not found file 로 reject
    2. 여러 preview 자산(png/json) 은 없어도 warn 후 계속 진행 (line 234-284)
    3. JSON 파싱 (line 297) → cpCapture.fromSkatResults(skatResults) 호출 (line 301)
    4. false 반환 시 line 306-308 에서 error log + reject
  • Failure point: packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:415-421unaligned_perspectives 순회 중 asset lookup 실패로 false 반환
packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:297-309typescript
const skatResults = JSON.parse(fs.readFileSync(localSkatSampledResultsFilePath).toString('utf8'));
logger.info('FileSystemManager::loadSkatResults | read file meta - created at: %s, skatSDK: %s'
    , skatResults.created, skatResults.sdk_version);

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();
}
packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:410-423typescript
// skat unaligned perspectives
if (skatResults.unaligned_perspectives != undefined) {
    logger.debug('CPCapture::fromSkatResults | unaligned perspectives size: %d', skatResults.unaligned_perspectives.length);
    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;
        }
    }
}
packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:246-250typescript
getAssetFromKey = (cpAssetKey: string): CPAsset | undefined => {
    if (this.cpAssets == undefined) return;

    return this.cpAssets.find(x => x && x.key === cpAssetKey);
};

기대 동작: skatmaster 산출물의 unaligned_perspectives[].key 는 항상 Tesla capture 의 asset 목록에 존재해야 한다 (skatmaster 는 해당 capture 의 assets 만 처리해야 하므로).

실제 동작: unaligned_perspectives 중 하나의 key(XlrXyIHkUzO) 가 cpAssets 에서 발견되지 않아 순회가 중단되고 skat 결과 전체가 폐기됨.

Log Evidence#

Datadog Query (재현용)

text
service:cupixworks-capture-postprocessor-agent @environment:production

시간 범위: 2026-07-13 15:05:30Z ~ 15:06:30Z (KST 2026-07-14 00:05:30 ~ 00:06:30)

핵심 로그 (시간순, 원문 그대로)

text
[00:05:56 KST] info  BaseService::runByMessage | id: 1192118
[00:05:56 KST] info  JobManager::loadJob | begin - job id: 1192118
[00:05:56 KST] info  JobManager::loadJob | end - job id: 1192118
[00:05:57 KST] info  CPCapture::fromMeta | key: 2jdyiKKRo, version: 1
[00:05:57 KST] info  CPCapture::fromSkatMasterResults | {"error_code":"","skatsdk_version":{"ver":"3.30.26\t2c6644a7e2192c73c3ce86276ac08e29b3df4123\t20260708_060625\tarm64\tUbuntu 22.04.5 LTS"},"task_name":""}
[00:05:57 KST] warn  FileSystemManager::loadSkatResults | end - not found file - /efs/c39ff4904e0a9f25/skatmaster/results/align_preview_default.png
[00:05:57 KST] warn  FileSystemManager::loadSkatResults | end - not found file - /efs/c39ff4904e0a9f25/skatmaster/results/align_preview_refinement_with_prior_map.png
[00:05:57 KST] warn  FileSystemManager::loadSkatResults | end - not found file - /efs/c39ff4904e0a9f25/skatmaster/results/align_preview_meta_refinement_with_prior_map.json
[00:05:57 KST] warn  FileSystemManager::loadSkatResults | end - not found file - /efs/c39ff4904e0a9f25/skatmaster/results/align_preview_meta_default.json
[00:05:57 KST] info  FileSystemManager::loadSkatResults | read file meta - created at: Mon Jul 13 15:05:35 2026 GMT, skatSDK: 3.30.26 ...
[00:05:57 KST] warn  CPCapture::fromSkatResult | not found asset - asset key: XlrXyIHkUzO
[00:05:57 KST] error FileSystemManager::loadSkatResults | end - failed to load skat results
[00:05:57 KST] warn  loadSkatResults: failed to load skat results
[00:05:57 KST] warn  CupixAuth::handleError | Undefined response: {"stack":"Error: loadSkatResults: failed to load skat results\n    at FileSystemManager.loadSkatResults (/tmp/agent/dist/app.cjs:9063:15)\n    at PostprocessorService.run (/tmp/agent/dist/app.cjs:9890:33)\n ..."}
[00:05:57 KST] info  AwsQueueManager::deleteMessage | end - message id: e2f71bfc-de00-4b47-8300-16f4488078ef
[00:05:58 KST] info  BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/733859
[00:05:58 KST] error BaseService::handlingMessageErrors | Error and message object - {"error":"undefined response","sqsMessage":{"MessageId":"e2f71bfc-de00-4b47-8300-16f4488078ef","Attributes":{"ApproximateReceiveCount":"1"}}}

해석

  • capture_alignments.json 은 정상 존재하고 (read file meta info 로그가 뜸), JSON 파싱까지 성공.
  • 파싱된 skat result 의 unaligned_perspectives 중 하나의 asset key XlrXyIHkUzO 가 capture 의 asset 목록에 부재 → fromSkatResults false → 최종 error.
  • capture id 733859 는 workspace path 로부터 확인됨 (/tmp/workspace/733859).
  • SQS message 가 즉시 deleteMessage 되고 재시도 없이 종료됨 (ApproximateReceiveCount:1).

14일 내 동일 오류 (broader 검색)

text
Datadog query:  service:cupixworks-capture-postprocessor-agent "failed to load skat results"
결과: 3 건 (error 레벨)
  - 2026-07-07 17:04:53 KST
  - 2026-07-07 17:29:42 KST
  - 2026-07-14 00:05:57 KST

산발적 발생 패턴이며, 서로 다른 capture 에서 나타나므로 단일 데이터 손상이 아닌 pipeline 정합성 이슈로 판단.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Skatmaster 산출물 (capture_alignments.json) 의 unaligned_perspectives[].key 와 Tesla API 의 capture assets 목록이 불일치 → CPCapture.getAssetFromKey 가 undefined 반환 → fromSkatResults false 실패 직전 로그 CPCapture::fromSkatResult | not found asset - asset key: XlrXyIHkUzO, 코드 cpcapture.ts:415-421 에서 return false, 이후 file-system.manager.ts:307 의 error 로그 그대로 재현 Confirmed
H2 capture_alignments.json 파일 자체가 없어서 실패 (line 229 의 error) line 229 는 not found file - {path} 메시지를 냄. 대다수 다른 클러스터가 이 메시지 이번 cluster 의 메시지는 ... failed to load skat results (line 307). 그리고 read file meta - created at: info 로그가 있어 파일이 읽혔음이 명백 Rejected
H3 align_preview_* 파일 부재로 인한 실패 4개의 preview 파일 not-found warn 로그 존재 해당 부재는 code line 245-283 에서 warn 후 계속 진행 (fromAlignPreviewResult 는 null 을 받으면서도 true 반환 가능). 실제 실패는 그 이후 fromSkatResults 에서 발생 Rejected
H4 Skat SDK 버전 호환성 이슈 (스키마 변경으로 json 파싱 실패) 로그에 SDK 버전 명시 (3.30.26) JSON.parse 는 성공했고 (read file meta info 로그가 파싱 후 필드에 접근한 결과), fromSkatResultsundefined 필드 방어 로직만 있음 Rejected
H5 외부 dependency 장애 (EFS, Tesla API) 동시간대 me-central-2 S3 로의 transfer::retry (2/3, 3/3) 관찰 Retry 는 다른 capture 의 S3 업로드 대상이며, 문제 capture 의 실패 지점은 로컬 로직(fromSkatResults) 이지 원격 호출 아님. status-board 도 dep incident 없음 Rejected

Fix Recommendation#

즉시 조치 (Critical)#

  • 문제 capture (id 733859) 개별 조치: skatmaster 산출물과 Tesla capture assets 간 불일치가 확정된 경우 해당 job 을 수동 재큐잉하거나 skip 처리. SQS 메시지가 이미 삭제(deleted)되어 자동 재시도가 일어나지 않음.
  • packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:415-421 — 이 지점을 즉시 코드 수정하는 것보다는, 먼저 데이터 불일치 원인 조사가 우선. 임의로 warn 후 continue 로 바꾸면 skatmaster 로부터 온 (이론상 유효한) 정렬 정보가 누락된 상태로 postprocess 가 진행될 수 있음 → 추가 downstream 문제 가능성. 조치 방향은 아래 단기 개선을 참조.

단기 개선 (1주 이내)#

  • 로그 강화: packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:419 의 warn 에 capture id, 현재 cpAssets 의 key 목록, unaligned_perspectives 총 개수, 문제 index 를 포함시키면 재발 시 upstream(skatmaster) 산출물 원본과 대조 가능.
  • 실패 정책 재검토: 현재는 하나의 asset 불일치로 skat 전체를 reject → capture 전체 postprocess 실패. 두 가지 옵션 검토 필요 (프로덕트/알고리즘 팀과 조율 필요):
    1. 불일치 항목만 skip 하고 나머지는 진행 (partial-success)
    2. 실패로 유지하되 SQS message 를 dead-letter queue 로 라우팅해 자동 손실 방지 (현재 AwsQueueManager::deleteMessage 로 바로 삭제됨)
  • skatmaster–Tesla 정합성 검증: skatmaster job 시작 시점에 Tesla capture 의 assets snapshot 을 캐싱해 두는지 확인. skatmaster 처리 도중 Tesla 에서 asset 이 삭제/재생성되면 key 가 어긋날 수 있음.

장기 개선 (재발 방지)#

  • Skatmaster 파이프라인 (별도 서비스) 이 결과 json 을 쓰기 전, 현재 capture 의 asset key 셋과 산출물 key 셋을 비교해 불일치 시 skatmaster 단계에서 실패시키기. 이렇게 하면 postprocessor 는 항상 정합 데이터를 받게 됨.
  • Postprocessor 실패 시 SQS 메시지 삭제 대신 재시도 정책(exponential backoff + DLQ) 도입.
  • unaligned_perspectives / unaligned_panos / clusters 스키마 검증을 postprocessor 진입 시점에 일괄 수행하는 validator 추가 (현재는 iteration 중 부분 검증).

Monitoring#

  • Datadog Timeseries widget 용 쿼리 (release dashboard 에 그대로 삽입 가능)
text
service:cupixworks-capture-postprocessor-agent status:error "failed to load skat results"
text
service:cupixworks-capture-postprocessor-agent status:warn "not found asset - asset key"
  • 알림: 위 첫 번째 쿼리가 1시간 내 3건 이상이면 slack 알림. 현재는 산발적이지만 upstream 파이프라인 이슈로 급증할 여지가 있음.

Risk Assessment#

  • Risk level: medium — 서비스 광역 장애는 아니나, SQS 메시지가 재시도 없이 삭제되므로 실패한 capture 는 사용자가 인지하기 전까지 postprocess 미완료 상태로 방치됨. 3건/14일의 산발적 패턴이 upstream 스키마/타이밍 변경으로 증가할 위험 있음.
  • 예상 복잡도: standard — 단기 개선(로그 강화, DLQ 도입) 은 pure-code 변경. 실패 정책(partial-success) 변경은 알고리즘/프로덕트 조율 필요.