SkatManager::applyPreprocessorResultToCapture - end - undefined result
RCA: SkatManager::applyPreprocessorResultToCapture - end - undefined result
Overview#
What Happened#
2026-04-24 00:04:40 UTC에 cupixworks-capture-singleshot-agent 서비스에서 capture 686695 처리 중 SKAT 네이티브 바이너리(SceneMapper)의 preprocessor가 undefined 결과를 반환하는 에러가 1건 발생했다. capture에 포함된 pano 파일이 JPEG가 아닌 MP4 동영상 파일이어서 SceneMapper가 이미지를 파싱하지 못한 것이 원인이다.
Quick Facts#
| Field | Value |
|---|---|
| exception.message | SkatManager::applyPreprocessorResultToCapture - end - undefined result |
| top_frame | Native SKAT binary (SceneMapper Maker label) |
| env | production, us-west-2 |
Affected Teams#
| Team / Domain | Error Count | Impact |
|---|---|---|
| qatest3 (team 1131) | 1 | capture 686695의 singleshot alignment 실패, 해당 캡처의 정렬 결과가 생성되지 않았을 가능성 높음 |
Timeline#
- 00:04:31Z — Agent가 SQS 메시지를 수신하여 capture 686695 처리 시작
- 00:04:31Z —
SingleshotService::runAlignScript호출, pano 다운로드 및 SKAT 실행 준비 - 00:04:38Z — Scene-Mapper 경고:
file[/tmp/workspace/686695/original_panos/82289916.mp4] is not jpeg image - 00:04:40Z —
SkatManager::applyPreprocessorResultToCapture - end - undefined result에러 발생 - 00:04:40Z —
SkatManager::run - end - undefined result from preprocessor에러 발생 (11ms 후) - 00:04:44Z — Agent가 workspace 정리 및 SQS 메시지 삭제 완료
Error Log#
SkatManager::applyPreprocessorResultToCapture - end - undefined result
Impact#
- Service:
cupixworks-capture-singleshot-agent - 발생 횟수: 1
- 최초 발생: 2026-04-24T00:04:40.591Z
- 최근 발생: 2026-04-24T00:04:40.591Z
Root Cause Summary#
Capture 686695에 포함된 pano(ID: 82289916)의 원본 파일이 JPEG 이미지가 아닌 MP4 동영상 파일이었다. align.module.ts에서 pano를 다운로드할 때 pano.name에서 파일 확장자를 추출하여 그대로 저장하는데, 이 pano의 이름에 .mp4 확장자가 포함되어 있어 동영상 파일이 그대로 다운로드되었다. 이후 네이티브 SKAT 바이너리(SceneMapper)가 이 파일을 original_panos/ 디렉토리에서 JPEG 이미지로 파싱하려 했으나 실패하여 preprocessor 결과가 undefined로 반환되었고, SkatManager::applyPreprocessorResultToCapture에서 이를 에러로 로깅한 것이다.
Technical Analysis#
Code Path#
- Entry point:
base-service.ts:170—this.run(targetId, msgObject)호출 singleshot-service.ts:41—this.runAlignScript(serverCapture)호출align.module.ts:24—runAlign()함수 시작
1단계: Pano 다운로드 및 파일 확장자 결정
const panoName = pano.name || `pano_${panoId}`;
const fileExt = panoName ? path.extname(panoName).toLowerCase() || '.jpg' : '.jpg';
const localFileName = `${panoKey}${fileExt}`;
const localFilePath = path.join(inputPanoDir, localFileName);
pano.name에서 확장자를 추출한다. pano 82289916의 name에 .mp4 확장자가 포함되어 있으면 fileExt가 .mp4가 되어, input_panos/82289916.mp4로 저장된다. JPEG 여부에 대한 validation이 없다.
2단계: SKAT 네이티브 바이너리 실행
// Process
const startTime = Date.now();
this.log('AlignProcess::execute | sceneMapper.process - begin');
this.sceneMapper.process();
this.log('AlignProcess::execute | sceneMapper.process - done');
sceneMapper.process()는 C++ 네이티브 바이너리를 호출한다. 이 바이너리가 input_panos/의 파일을 original_panos/로 복사/이동한 후 JPEG 파싱을 시도한다. MP4 파일을 JPEG로 파싱할 수 없어 preprocessor가 undefined 결과를 반환한다.
3단계: 에러 전파
네이티브 바이너리 내부에서 SkatManager::applyPreprocessorResultToCapture가 preprocessor 결과를 capture에 적용하려 하지만 결과가 undefined이므로 에러를 로깅한다. 이어서 SkatManager::run도 undefined result from preprocessor 에러를 로깅한다.
- Failure point: 네이티브 SKAT 바이너리 내부
SkatManager::applyPreprocessorResultToCapture(C++ 코드, 소스 접근 불가)
4단계: 에러 후 처리 계속
에러가 발생했지만 네이티브 프로세스가 크래시하지 않고 반환되었고, agent는 정상적으로 workspace 정리(BaseService::cleanUpAnythingRelatedModel)와 SQS 메시지 삭제를 수행했다.
const alignmentResult = result.alignment;
if (!alignmentResult || !alignmentResult.clusters) {
logger.error('runAlign | no alignment result');
return { success: false };
}
네이티브 바이너리가 에러를 로깅하면서도 alignment result를 비정상적으로 반환했을 가능성이 있다. 만약 result.alignment이 빈 객체이거나 clusters가 없으면 { success: false }를 반환하며, runAlignScript는 에러를 throw하지 않으므로 singleshot-service.ts:42의 uploadStitchedPano가 이어서 실행된다.
Log Evidence#
Datadog 검색 쿼리:
service:cupixworks-capture-singleshot-agent status:error @environment:production
service:cupixworks-capture-singleshot-agent 686695
에러 로그 2건 (capture 686695):
{
"timestamp": "2026-04-24T00:04:40.591Z",
"level": "error",
"label": "Maker",
"message": "SkatManager::applyPreprocessorResultToCapture - end - undefined result",
"log_file": "/tmp/workspace/686695/maker-json.log",
"capture_id": 686695
}
{
"timestamp": "2026-04-24T00:04:40.602Z",
"level": "error",
"label": "Maker",
"message": "SkatManager::run - end - undefined result from preprocessor",
"log_file": "/tmp/workspace/686695/maker-json.log",
"capture_id": 686695
}
선행 경고 (Scene-Mapper label):
{
"timestamp": "2026-04-24T00:04:38.523Z",
"level": "warn",
"label": "Scene-Mapper",
"message": "[02999.45] | Error - file[/tmp/workspace/686695/original_panos/82289916.mp4] is not jpeg image."
}
동일 시간대 정상 처리된 capture (686000, 686001):
같은 호스트(ip-10-1-161-162.us-west-2.compute.internal)에서 직전에 처리된 capture 686000, 686001은 SkatManager 에러 없이 정상 완료되었다. 이는 문제가 시스템적 장애가 아닌 capture 686695의 입력 데이터에 국한됨을 확인한다.
36시간 검색 범위(2026-04-23T00:00:00Z ~ 2026-04-24T12:00:00Z)에서 "undefined result" 에러는 이 2건만 발견되었다.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | Capture 686695의 pano 원본 파일이 JPEG가 아닌 MP4 동영상이어서 SKAT preprocessor가 파싱 실패 | Scene-Mapper warn 로그: file[...82289916.mp4] is not jpeg image (00:04:38Z), 에러 발생 2초 전. align.module.ts:57에서 pano.name의 확장자를 그대로 사용하여 .mp4로 다운로드 |
— | Confirmed |
| H2 | SKAT 네이티브 바이너리 버그로 정상 JPEG도 파싱 실패 | — | 동일 호스트에서 직전에 처리된 capture 686000, 686001은 정상 완료. 36시간 내 해당 에러 1건뿐 | Rejected |
| H3 | 네트워크 오류로 pano 다운로드가 불완전하여 손상된 파일 전달 | 다운로드 실패 시 이론적으로 가능 | Scene-Mapper가 .mp4 확장자를 명시적으로 언급. 다운로드 실패 시 align.module.ts:361에서 reject 발생하여 별도 에러 로그 남았을 것. 해당 에러 로그 없음 |
Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
align.module.ts:56-58에서 pano 다운로드 전에 파일 확장자를 검증하고, JPEG/PNG 등 지원되는 이미지 형식이 아닌 경우 경고 로그를 남기고 해당 pano를 skip하거나, 강제로.jpg로 다운로드 후 실제 이미지 여부를 확인하는 로직 추가- 또는 API에서 pano를 조회할 때
pano.name에 비이미지 확장자가 포함된 경우를 사전 필터링
단기 개선 (1주 이내)#
runAlign함수에서sceneMapper.process()실행 후 반환된 결과를 검증할 때, 에러 원인(어떤 pano가 실패했는지)을 TypeScript 레이어에서도 로깅하도록 개선. 현재는 네이티브 바이너리의 Maker 로그에만 의존- capture 686695의 pano 82289916이 왜 MP4 이름으로 등록되었는지 데이터 원인 조사 필요 (사용자 업로드 오류 또는 API 버그)
장기 개선 (재발 방지)#
- SKAT 네이티브 바이너리에서 비이미지 파일을 만났을 때
undefined가 아닌 명시적 에러 코드를 반환하도록 개선 - pano 업로드 파이프라인(tesla API 측)에서 이미지 형식 validation을 강화하여 MP4 등 비이미지 파일이 pano로 등록되지 않도록 방지
Monitoring#
- SKAT preprocessor
undefined result에러 모니터링:
service:cupixworks-capture-singleshot-agent status:error "undefined result"
- Scene-Mapper의 비이미지 파일 경고 모니터링:
service:cupixworks-capture-singleshot-agent "is not jpeg image"
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 이 에러는 특정 capture의 입력 데이터 이상에 의한 단발성 이벤트로, 시스템적 영향은 없다. 다만 사용자가 MP4 파일을 pano로 업로드하는 경우가 반복될 수 있으므로 입력 검증 강화가 권장된다.