ES /docs

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#

  1. 2026-04-24 09:04:31 KSTBaseService::runByMessage 시작, capture 686695 처리 개시
  2. 2026-04-24 09:04:31 KSTSingleshotService::runAlignScript 호출, workspace /tmp/workspace/686695 설정
  3. 2026-04-24 09:04:38 KST — SKAT SDK가 82289916.mp4 파일을 JPEG이 아니라고 거부 (warn 로그)
  4. 2026-04-24 09:04:40 KSTSkatManager::applyPreprocessorResultToCapture — undefined result 에러 발생
  5. 2026-04-24 09:04:40 KSTSkatManager::run 에러로 종료
  6. 2026-04-24 09:04:44 KST — workspace cleanup 완료, SQS 메시지 삭제

Error Log#

Datadog Logs

text
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:170await this.run(targetId, msgObject)
  • singleshot-service.ts:41await this.runAlignScript(serverCapture)
cupix-tesla-singleshot-agent/src/singleshot-service.ts:37-44typescript
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 다운로드 시 파일명 결정
cupix-tesla-singleshot-agent/src/align/align.module.ts:55-63typescript
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의 name82289916.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)와 동일한 패턴을 따른다:

cupix-capture-preprocessor-agent/src/preprocessor-service.ts:1028-1039typescript
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 쿼리:

text
service:cupixworks-capture-singleshot-agent 686695

실행 시작 로그 (capture 686695 처리 개시):

text
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 파일 거부 로그 (핵심 원인):

text
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 에러:

text
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:

text
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 기반)로 업데이트한다. 현재 배포된 이미지는 legacy SkatManager 기반 코드를 사용하고 있다.

Monitoring#

  • SKAT SDK의 비이미지 파일 거부 패턴 모니터링:
text
service:cupixworks-capture-singleshot-agent "is not jpeg image"
  • Preprocessor undefined result 에러 추적:
text
service:cupixworks-capture-singleshot-agent status:error "undefined result from preprocessor"

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial — 입력 데이터 문제이며 코드 변경 없이 해결 가능. 단기 개선(입력 검증 추가)도 간단한 변경.