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.fromSkatResults 가 false 를 반환했고, 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#
- 2026-07-13 23:58:34 KST — skatmaster 가 이전 capture (
/efs/9c4103bbb0e54f16) 의 결과 생성 (참고용 시각) - 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) - 2026-07-14 00:05:56 KST —
BaseService::runByMessage | id: 1192118— 문제 job 소비 시작 - 2026-07-14 00:05:57 KST —
CPCapture::fromMeta | key: 2jdyiKKRo, version: 1— capture data 로드 - 2026-07-14 00:05:57 KST —
CPCapture::fromSkatResult | not found asset - asset key: XlrXyIHkUzO(warn) - 2026-07-14 00:05:57 KST —
FileSystemManager::loadSkatResults | end - failed to load skat results(error) - 2026-07-14 00:05:57 KST — SQS message
e2f71bfc-de00-4b47-8300-16f4488078ef삭제 (재시도 없이 dead) - 2026-07-14 00:05:58 KST —
BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/733859— workspace 정리
Error Log#
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.json 의 unaligned_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:99—PostprocessorService.run이fileSystemManager.loadSkatResults(cpCapture, this.actionName)호출 packages/cupix-capture-postprocessor-agent/src/manager/file-system.manager.ts:205-310—loadSkatResults는 다음 순서로 수행capture_alignments.json(skatSampled) 존재 확인 → 존재해야 함, 아니면 line 229 에서not found file로 reject- 여러 preview 자산(png/json) 은 없어도
warn후 계속 진행 (line 234-284) - JSON 파싱 (line 297) →
cpCapture.fromSkatResults(skatResults)호출 (line 301) - false 반환 시 line 306-308 에서 error log + reject
- Failure point:
packages/cupix-capture-postprocessor-agent/src/model/cpcapture.ts:415-421—unaligned_perspectives순회 중 asset lookup 실패로false반환
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();
}
// 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;
}
}
}
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 (재현용)
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)
핵심 로그 (시간순, 원문 그대로)
[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 metainfo 로그가 뜸), JSON 파싱까지 성공.- 파싱된 skat result 의
unaligned_perspectives중 하나의 asset keyXlrXyIHkUzO가 capture 의 asset 목록에 부재 →fromSkatResultsfalse → 최종 error. - capture id 733859 는 workspace path 로부터 확인됨 (
/tmp/workspace/733859). - SQS message 가 즉시
deleteMessage되고 재시도 없이 종료됨 (ApproximateReceiveCount:1).
14일 내 동일 오류 (broader 검색)
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 로그가 파싱 후 필드에 접근한 결과), fromSkatResults 는 undefined 필드 방어 로직만 있음 |
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 실패. 두 가지 옵션 검토 필요 (프로덕트/알고리즘 팀과 조율 필요):
- 불일치 항목만 skip 하고 나머지는 진행 (partial-success)
- 실패로 유지하되 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 에 그대로 삽입 가능)
service:cupixworks-capture-postprocessor-agent status:error "failed to load skat results"
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) 변경은 알고리즘/프로덕트 조율 필요.