SkatManager::run - end - undefined result from preprocessor
RCA: SkatManager::run - end - undefined result from preprocessor
Overview#
What Happened#
2026-04-24T00:04:40Z에 cupixworks-capture-singleshot-agent 서비스(us-west-2)에서 capture 686695 처리 중 SKAT SDK의 preprocessor가 .mp4 파일을 JPEG 이미지로 처리하지 못해 결과가 undefined로 반환되었고, 이로 인해 SkatManager::run이 에러로 종료되었다. 1건 발생.
Quick Facts#
| Field | Value |
|---|---|
| exception.message | SkatManager::run - end - undefined result from preprocessor |
| top_frame | SkatManager::applyPreprocessorResultToCapture (legacy code, not in current repo) |
| env | production, us-west-2 |
Affected Teams#
| Team / Domain | Error Count | Impact |
|---|---|---|
| qatest3 (team_id: 1131) | 1 | capture 686695의 singleshot alignment 실패, 해당 캡처의 파노라마 정렬 미완료 |
Timeline#
- 2026-04-24 09:04:31 KST —
BaseService::runByMessage시작, capture 686695 처리 개시 - 2026-04-24 09:04:31 KST —
SingleshotService::runAlignScript호출, workspace/tmp/workspace/686695설정 - 2026-04-24 09:04:38 KST — SKAT SDK가
82289916.mp4파일을 JPEG이 아니라고 거부 (warn 로그) - 2026-04-24 09:04:40 KST —
SkatManager::applyPreprocessorResultToCapture— undefined result 에러 발생 - 2026-04-24 09:04:40 KST —
SkatManager::run에러로 종료 - 2026-04-24 09:04:44 KST — workspace cleanup 완료, SQS 메시지 삭제
Error Log#
SkatManager::run - end - undefined result from preprocessor
Impact#
- Service:
cupixworks-capture-singleshot-agent - 발생 횟수: 1
- 최초 발생: 2026-04-24T00:04:40.602Z
- 최근 발생: 2026-04-24T00:04:40.602Z
Root Cause Summary#
Capture 686695의 pano 중 하나(id: 82289916)가 .mp4 확장자를 가진 파일로 서버에 업로드되어 있었다. Singleshot agent가 이 pano를 다운로드하여 original_panos 디렉토리에 82289916.mp4로 저장한 후, SKAT SDK(SceneMapper)의 preprocessor가 이 파일을 처리하려고 했으나 JPEG 이미지가 아니므로 거부했다. Preprocessor가 유효한 결과를 반환하지 못해 undefined가 되었고, SkatManager::applyPreprocessorResultToCapture에서 이를 감지하여 에러로 보고했다. 이는 사용자가 .mp4 파일을 pano로 잘못 업로드한 데이터 문제이며, 코드 버그가 아닌 입력 데이터 유효성 검증 부재로 인한 문제이다.
Technical Analysis#
Code Path#
이 에러는 legacy 코드(배포된 Docker 이미지에 존재하는 SkatManager 클래스)에서 발생했다. 현재 소스코드는 SkatManager를 사용하지 않고 runAlign 함수로 리팩토링되었지만, 배포된 이미지는 아직 구버전을 실행하고 있다.
현재 코드 기준 동일 실행 흐름:
- Entry point:
base-service.ts:170—await this.run(targetId, msgObject) singleshot-service.ts:41—await this.runAlignScript(serverCapture)
protected run = async (targetId: number, msgObject: any): Promise<void> => {
const serverCapture = await this.getCaptureById(targetId);
if (serverCapture) {
await this.updateCaptureSingleshotState(targetId, TESLA.UpdateCaptureRequest.SingleshotStateEnum.Running);
await this.runAlignScript(serverCapture);
await this.uploadStitchedPano(targetId);
await this.updateCaptureSingleshotState(targetId, TESLA.UpdateCaptureRequest.SingleshotStateEnum.Stopped);
}
};
align.module.ts:52-63— pano 다운로드 시 파일명 결정
const panoId = pano.id;
const panoKey = pano.uuid || panoId.toString();
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);
const downloadUrl = `${cupixAuth.apiUrl}/panos/${panoId}/download?original=true`;
await downloadFile(downloadUrl, localFilePath, { 'X-CUPIX-AUTH': cupixAuth.accessToken });
여기서 panoName에서 확장자를 추출한다. 만약 pano의 name이 82289916.mp4이면 fileExt는 .mp4가 되고, 파일이 original_panos/82289916.mp4로 저장된다.
- Failure point: SKAT SDK의 native preprocessor —
.mp4파일을 JPEG으로 읽으려 시도 후 실패 - 기대 동작: pano 파일은 JPEG/PNG 이미지여야 하며, preprocessor가 유효한 결과를 반환해야 함
- 실제 동작:
.mp4파일이 pano로 존재하여 preprocessor가 결과 없이 반환 →undefined result
Legacy 코드(배포 이미지)에서의 applyPreprocessorResultToCapture 메서드는 현재 코드의 applyPreprocessorResults (preprocessor-service.ts:1028)와 동일한 패턴을 따른다:
private applyPreprocessorResults = (cpCapture: CPCapture, results: PreprocessorResults): boolean => {
logger.debug('PreprocessorService::applyPreprocessorResults | begin');
if (this.preprocessorLogManager.logWatcher) {
logger.debug('PreprocessorService::applyPreprocessorResults | close preprocessorLogManager');
this.preprocessorLogManager.logWatcher.close();
}
if (results == undefined) {
logger.error('PreprocessorService::applyPreprocessorResults | end - undefined results');
this.jobManager.setErrorCode(ErrorCode.Agent.UnknownPreprocessorResults);
return false;
}
Log Evidence#
Datadog 쿼리:
service:cupixworks-capture-singleshot-agent 686695
실행 시작 로그 (capture 686695 처리 개시):
2026-04-24 09:04:31 KST | info | BaseService::runByMessage | id: 686695
2026-04-24 09:04:31 KST | info | SingleshotService::getCaptureById | captureId: 686695
2026-04-24 09:04:31 KST | info | SingleshotService::runAlignScript | params: {"workspace":"/tmp/workspace/686695","env_name":"production","api_endpoint":"http://api-tesla.cupix.internal/api/v1","session_id":10610855,"session_token":"vgilelh4hakf","aws_region":"us-west-2","capture_id":686695,"team_id":1131,"team_domain":"qatest3","user_id":43947,"email":"juseok.oh@cupix.io"}
SKAT SDK의 .mp4 파일 거부 로그 (핵심 원인):
2026-04-24 09:04:38 KST | warn | [02999.45] | Error - file[/tmp/workspace/686695/original_panos/82289916.mp4] is not jpeg image.
Preprocessor 결과 undefined 에러:
2026-04-24 09:04:40 KST | error | SkatManager::applyPreprocessorResultToCapture - end - undefined result
2026-04-24 09:04:40 KST | error | SkatManager::run - end - undefined result from preprocessor
처리 후 cleanup:
2026-04-24 09:04:44 KST | info | BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/686695
2026-04-24 09:04:44 KST | info | AwsQueueManager::deleteMessage | begin - queue url: https://sqs.us-west-2.amazonaws.com/002596530511/cupix-tesla-singleshot-agent-production
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | .mp4 파일이 pano로 잘못 업로드되어 SKAT SDK preprocessor가 JPEG으로 처리 불가 |
warn 로그: file[/tmp/workspace/686695/original_panos/82289916.mp4] is not jpeg image. — preprocessor가 .mp4를 거부함. 직후 undefined result 에러 발생 |
— | Confirmed |
| H2 | SKAT SDK 자체 버그로 유효한 이미지 파일도 처리 실패 | — | 동일 시간대 다른 capture(686000, 686001)는 정상 완료됨. .mp4 파일이 아닌 경우 정상 처리 |
Rejected |
| H3 | 네트워크 오류로 pano 다운로드가 불완전 | — | 로그에 다운로드 실패 없음. 파일이 존재하되 .mp4 형식인 것이 문제. cleanup 로그에서 workspace가 정상 존재함 확인 |
Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
- 수정 불필요. 이 에러는 사용자(qatest3 팀)가
.mp4파일을 pano로 잘못 업로드한 데이터 문제이다. Capture 686695의 pano 82289916을 확인하고, 필요시 올바른 이미지 파일로 재업로드하도록 사용자에게 안내.
단기 개선 (1주 이내)#
- Singleshot agent의 pano 다운로드 단계에서 파일 확장자 또는 MIME 타입 검증을 추가한다.
align.module.ts:57부근에서fileExt가 이미지 형식(.jpg,.jpeg,.png)이 아닌 경우 해당 pano를 건너뛰고 warn 로그를 남기도록 한다. - 에러 메시지를 개선하여 어떤 파일이 문제인지 구체적으로 표시한다. 현재 legacy 코드는 "undefined result from preprocessor"만 기록하여 원인 파악이 어렵다.
장기 개선 (재발 방지)#
- Tesla API의 pano 업로드 endpoint에서 파일 형식 검증을 추가하여 비이미지 파일이 pano로 업로드되는 것을 원천 차단한다.
- Singleshot agent의 배포 이미지를 현재 코드베이스(
runAlign기반)로 업데이트한다. 현재 배포된 이미지는 legacySkatManager기반 코드를 사용하고 있다.
Monitoring#
- SKAT SDK의 비이미지 파일 거부 패턴 모니터링:
service:cupixworks-capture-singleshot-agent "is not jpeg image"
- Preprocessor undefined result 에러 추적:
service:cupixworks-capture-singleshot-agent status:error "undefined result from preprocessor"
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial — 입력 데이터 문제이며 코드 변경 없이 해결 가능. 단기 개선(입력 검증 추가)도 간단한 변경.