not found refined align_preview_meta_refinement_with_prior_map.json
RCA: not found refined align_preview_meta_refinement_with_prior_map.json
Overview#
What Happened#
2026-07-14 15:37 KST 경 cupixworks-capture-refinement-arm-instance (Capture Refinement Agent) 가 서로 다른 두 개의 캡처(734539, 734484) 처리 중 copyAlignmentToEfs 단계에서 refinement 결과 파일 align_preview_meta_refinement_with_prior_map.json 을 로컬 결과 디렉토리에서 찾지 못해 job 을 실패시켰다. Refinement 는 완료되었지만 scenemapper child process 가 이 특정 산출물을 생성하지 못한 상태로 종료된 것으로, 두 캡처 모두 clark-vdc 팀(us-west-2) 소속이다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | Error |
| exception.message | not found refined align_preview_meta_refinement_with_prior_map.json |
| top_frame | RefinementService.copyAlignmentToEfs (/tmp/agent/dist/app.cjs:7467:15) (source: applications/agents/packages/cupix-capture-refinement-agent/src/refinement-service.ts:381) |
| runtime | Node.js agent bundle (/tmp/agent/dist/app.cjs) on arm instance |
| env | production, us-west-2 |
| affected captures | 734539 (job 1194919, host 4e2b6d37118e), 734484 (job 1194920, host 4769d35ddbc5) |
Affected Teams#
| Team / Domain | Error Count | Impact |
|---|---|---|
| clark-vdc (team.id 87) | 2 | Capture refinement job 이 실패 처리되어 해당 두 캡처의 refined alignment / preview 산출물이 EFS 로 승격되지 못함 |
Timeline#
- 2026-07-14 15:30 KST — 다수의 refinement 서비스 인스턴스(다른 hosts)가 동시에 job 을 loadJob 하며 정상 부트업 (
RefinementService::run | begin,JobManager::loadJob | end로그 확인) - 2026-07-14 15:36:59 KST — scenemapper 로부터
Grid map is not available or empty. Cannot calculate alignment quality.warning 발생 ([124603.75]스코어 태그) - 2026-07-14 15:37:45 KST — capture 734539 (job 1194919, host
4e2b6d37118e) 에서Error: not found refined align_preview_meta_refinement_with_prior_map.json발생 (first_seen) - 2026-07-14 15:38:17 KST — capture 734484 (job 1194920, host
4769d35ddbc5) 에서 동일 에러 발생 (last_seen). 이후 각 인스턴스는RefinementService::terminateService | force shutdown after 10 seconds로 강제 종료
Error Log#
not found refined align_preview_meta_refinement_with_prior_map.json
Stack (from Datadog raw log attribute stack):
Error: not found refined align_preview_meta_refinement_with_prior_map.json
at RefinementService.copyAlignmentToEfs (/tmp/agent/dist/app.cjs:7467:15)
at async RefinementService.run (/tmp/agent/dist/app.cjs:7210:11)
at async RefinementService.init (/tmp/agent/dist/app.cjs:7165:7)
Impact#
- Service:
cupixworks-capture-refinement-arm-instance - Team: clark-vdc
- 발생 횟수: 2 (클러스터 집계 기준)
- 최초 발생: 2026-07-14 15:37 KST
- 최근 발생: 2026-07-14 15:38 KST
- 부가 영향: 실패한 job 은
updateErrorActionJob('refinement')로 마킹 (refinement-service.ts:109). 후속 3D reconstruction 파이프라인은 refined alignment 파일 없이는 dense mapping 판단(checkAndCopyForReconstruction) 을 진행하지 못하므로 해당 캡처 두 건은 재처리(재-refinement) 없이는 완료되지 않는다.
Root Cause Summary#
Refinement agent 는 scenemapper child process 를 실행한 뒤 copyAlignmentToEfs 단계에서 로컬 결과 디렉토리(cpCapture.resultsDirPath) 에 있는 refinement 산출물들을 EFS 로 복사한다. 이 함수는 align_preview_meta_refinement_with_prior_map.json 이 존재하지 않으면(CPUtils.getFileSize(...) <= 0) ErrorCode.ScenemapperUtils.RefinerNotFoundInputFiles 를 세팅하고 예외를 던지도록 하드 게이팅되어 있다. 두 캡처 모두 scenemapper 자체는 실행됐지만("Grid map is not available or empty" warning 이 scenemapper 로부터 선행 출력됨) alignment 품질을 계산할 수 있는 유효한 grid map 이 없어 해당 산출물을 생성하지 못한 채 refinement 를 종료했다. 즉, 근본 원인은 이 두 캡처의 입력(alignment_archive.bin 또는 unrefined cluster) 이 scenemapper 가 유의미한 refinement 결과를 만들기에 부족한 상태였고, agent 는 이러한 "scenemapper 는 성공했으나 특정 산출물이 비었음" 상태를 별도 error code 없이 단일 RefinerNotFoundInputFiles 로 처리하고 있어 상위 파이프라인이 원인을 구분하지 못하고 있다는 점이다.
Technical Analysis#
Code Path#
- Entry point:
applications/agents/packages/cupix-capture-refinement-agent/src/refinement-service.ts:79—RefinementService.run() - 전체 흐름:
run → runRefinement (scenemapper child process 실행) → copyAlignmentToEfs (결과 파일 EFS 복사) - Failure point:
applications/agents/packages/cupix-capture-refinement-agent/src/refinement-service.ts:381
run() 의 orchestration:
private run = async (): Promise<void> => {
logger.info('RefinementService::run | begin');
try {
const srvJob = await this.jobManager.loadJob(Environment.CPX_JOB_ID as number);
await this.jobManager.updateRunningActionJob('refinement');
const cpCapture = srvJob ? await this.createCPCaptureByJob(srvJob) : undefined;
if (cpCapture) {
this.checkInputFiles();
// ...
await this.runRefinement(cpCapture);
await this.copyAlignmentToEfs(cpCapture); // ← 여기서 throw
await this.copyPreviewImageToEfs(cpCapture);
await this.checkAndCopyForReconstruction(cpCapture);
// ...
}
logger.info('RefinementService::run | end');
await this.jobManager.updateCompleteActionJob('refinement', TESLA.UpdateJobRequest.StateEnum.Stopped);
} catch (error) {
logger.error('RefinementService::run | end - %s', JSON.stringify(error));
await this.jobManager.updateErrorActionJob('refinement');
}
};
문제의 게이트:
const alignPreviewRefinementFileEfsPath = path.join(skatMasterEfsPath, Constants.DefaultAlignPreviewRefinementJsonFileName);
const alignPreviewRefinementFileLocalPath = path.join(cpCapture.resultsDirPath, Constants.DefaultAlignPreviewRefinementJsonFileName);
if (CPUtils.getFileSize(alignPreviewRefinementFileLocalPath) > 0) {
const start = new Date().getTime();
this.renameExistingFile(alignPreviewRefinementFileEfsPath);
fs.copyFileSync(alignPreviewRefinementFileLocalPath, alignPreviewRefinementFileEfsPath);
const durationTime = new Date().getTime() - start;
logger.debug('RefinementService::copyAlignmentToEfs | copy refined %s - duration: %d ms, size: %d bytes', Constants.DefaultAlignPreviewRefinementJsonFileName, durationTime, CPUtils.getFileSize(alignPreviewRefinementFileLocalPath));
} else {
logger.warn('RefinementService::copyAlignmentToEfs | not found refined %s', Constants.DefaultAlignPreviewRefinementJsonFileName);
this.jobManager.setErrorCode(ErrorCode.ScenemapperUtils.RefinerNotFoundInputFiles);
throw new Error('not found refined align_preview_meta_refinement_with_prior_map.json');
}
DefaultAlignPreviewRefinementJsonFileName 상수 정의:
export const DefaultAlignPreviewRefinementJsonFileName = 'align_preview_meta_refinement_with_prior_map.json';
scenemapper wrapper 는 execute 에서 예외를 잡아 warn 으로만 로깅하고, 실제 산출물 존재 여부는 후행 파일 시스템 체크에 위임한다:
execute = async (params: RefinerParams): Promise<void> => {
await this.ensureInitialized();
try {
await this.childProcessManager.execute('execute', params);
} catch (error) {
logger.warn('ScenemapperManager::execute | error - %s', error);
if (this.setJobErrorCode) this.setJobErrorCode(ErrorCode.ScenemapperUtils.RefinerExecute);
throw error;
}
};
기대 동작 vs 실제 동작:
- 기대: scenemapper 가 유효한 grid map 을 이용해 refinement 를 수행하고
align_preview_meta_refinement_with_prior_map.json을 결과 디렉토리에 생성 →copyAlignmentToEfs가 EFS 로 승격 - 실제: scenemapper 는 실행됐으나
Grid map is not available or empty. Cannot calculate alignment quality.경고를 남기고 해당 산출물을 생성하지 않은 채 정상 종료 →getFileSize <= 0조건에 걸려RefinerNotFoundInputFiles로 job 실패 처리
Note: 다른 산출물 3종(capture_alignments_all.json, capture_alignments_sampled.json, align_preview.json)은 if 브랜치에서 logger.warn 만 남기고 넘어가는 반면, align_preview_meta_refinement_with_prior_map.json 하나만 throw 하도록 되어 있다. 이는 이 파일이 후속 단계(checkAndCopyForReconstruction 의 available_json_for_reconstruction 호출 및 downstream reconstruction) 에서 필수 입력으로 사용된다고 추정되기 때문으로 보이지만, 코드 상 명시적 문서화는 없다 (uncertain -- needs verification).
Log Evidence#
Datadog 쿼리 (재현용):
service:cupixworks-capture-refinement-arm-instance @environment:production "not found refined align_preview_meta_refinement_with_prior_map.json"
핵심 에러 로그 원문 (raw attribute):
{
"stack": "Error: not found refined align_preview_meta_refinement_with_prior_map.json\n at RefinementService.copyAlignmentToEfs (/tmp/agent/dist/app.cjs:7467:15)\n at async RefinementService.run (/tmp/agent/dist/app.cjs:7210:11)\n at async RefinementService.init (/tmp/agent/dist/app.cjs:7165:7)",
"level": "error",
"session": { "id": "4fdf37af58d3ef3843f0281770c366eb580eb1d5" },
"capture": { "id": 734484 },
"team": { "domain": "clark-vdc", "id": 87 },
"job": { "id": 1194920 },
"region": "us-west-2",
"host": { "name": "4769d35ddbc5" },
"@timestamp": "2026-07-14T06:38:17.718Z"
}
{
"stack": "Error: not found refined align_preview_meta_refinement_with_prior_map.json\n at RefinementService.copyAlignmentToEfs (/tmp/agent/dist/app.cjs:7467:15)\n at async RefinementService.run (/tmp/agent/dist/app.cjs:7210:11)\n at async RefinementService.init (/tmp/agent/dist/app.cjs:7165:7)",
"capture": { "id": 734539 },
"team": { "domain": "clark-vdc" },
"job": { "id": 1194919 },
"host": { "name": "4e2b6d37118e" },
"@timestamp": "2026-07-14T06:37:45.182Z"
}
동일 시간대 warn 시퀀스 (같은 인스턴스, copyAlignmentToEfs 함수 로그 그대로):
2026-07-14T06:36:59Z warn [124603.75] | Grid map is not available or empty. Cannot calculate alignment quality.
2026-07-14T06:38:17Z warn RefinementService::copyAlignmentToEfs | not found refined align_preview_meta_refinement_with_prior_map.json
2026-07-14T06:38:17Z error not found refined align_preview_meta_refinement_with_prior_map.json
같은 서비스에서 이 에러 메시지의 전체 14일 발생 이력 (직전 이틀):
2026-07-13 23:46:09
2026-07-14 02:59:23
2026-07-14 03:42:08
2026-07-14 03:44:50
2026-07-14 06:37:01
2026-07-14 07:51:34
동일 서비스에서 관측된 관련 크래시 신호(scenemapper child process):
2026-07-14 12:05:50 error Process killed by signal SIGSEGV (code: null)
2026-07-14 12:05:50 error ChildProcessManager::setupEventHandlers | Child process exited
- 이 에러는 클러스터의 2건 외에도 최근 이틀 동안 여러 번 반복되고 있으므로 일회성 이벤트가 아니라 재발성 패턴이다.
- 동일 시간대 scenemapper SIGSEGV 도 관측되는 것으로 보아 refinement 파이프라인 자체의 안정성 이슈가 있는 것으로 보이지만, 이 클러스터의 두 이벤트에서 SIGSEGV 로그는 확인되지 않았다 (uncertain -- 두 사건이 같은 근본 원인인지는 별도 조사 필요).
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | Scenemapper 가 유효한 grid map 부재로 refinement 결과(align_preview_meta_refinement_with_prior_map.json) 를 생성하지 못했다 |
에러 발생 시점 인근에 scenemapper 의 [124603.75] Grid map is not available or empty. Cannot calculate alignment quality. warn 이 반복 출력됨. refinement-service.ts:372 의 CPUtils.getFileSize(...) > 0 게이트가 false 로 떨어짐. Stack 이 copyAlignmentToEfs 로만 되어 있어 scenemapper 자체는 예외를 던지지 않고 종료 |
— | Confirmed |
| H2 | Scenemapper child process 가 SIGSEGV 로 죽어 산출물을 남기지 못했다 | 같은 서비스에서 2026-07-14 12:05:50 에 Process killed by signal SIGSEGV 관측됨 |
이 클러스터의 두 이벤트 시간대(06:37-06:38)에는 SIGSEGV 로그가 없고, ScenemapperManager::execute 의 try/catch 도 warn 을 남기지 않았음. 대신 Grid map is not available warn 이 정상적으로 출력됨 → child process 는 정상 종료 |
Rejected (for this cluster) |
| H3 | alignment_archive.bin 등 입력 파일 자체가 없어서 실패 |
입력 파일이 없으면 checkInputFiles 에서 먼저 not found alignment_archive.bin 로 실패해야 하는데, 클러스터의 에러 메시지와 stack 이 copyAlignmentToEfs 로 확정됨 (refinement-service.ts:148-152 vs :381) |
Stack 이 checkInputFiles 를 거치지 않음 |
Rejected |
| H4 | EFS 마운트/권한 문제로 파일 복사 실패 | — | 실패 지점은 EFS 로의 fs.copyFileSync 이전 단계인 로컬 파일 사이즈 체크(CPUtils.getFileSize(alignPreviewRefinementFileLocalPath)). 로컬 파일이 없다는 뜻이므로 EFS 관련 아님 |
Rejected |
| H5 | 코드 경로가 이 특정 파일 하나만 fatal 로 취급하는 게 과도한 게이팅이고, 실제로는 partial success 로 처리 가능 | 다른 3개 산출물은 동일 코드에서 warn 만 남기고 통과. 오직 이 파일만 throw (refinement-service.ts:378-382) |
이 파일이 downstream reconstruction 판단(checkAndCopyForReconstruction → available_json_for_reconstruction) 의 필수 입력일 가능성 있음(코드상 문서 없음) |
Inconclusive — 정책 결정 필요 (product/algorithm 팀 확인 대상) |
Fix Recommendation#
즉시 조치 (Critical)#
- 즉시 코드 변경은 없음. 이 두 캡처(734539, 734484)에 대해 refinement 를 재실행하거나 입력(
selected_unrefined_cluster_id/ 원본 alignment) 상태를 검토해 수동 재처리 필요. - clark-vdc 팀 관측: 최근 이틀 동안 동일 에러가 6건 이상 반복되고 있으므로 SRE / 3D reconstruction owner 에게 알림 채널로 공유 필요. (외부 조율 항목이므로 자동 code-fix 에서는 제외)
단기 개선 (1주 이내)#
- 대상 파일:
applications/agents/packages/cupix-capture-refinement-agent/src/refinement-service.ts:378-382- 관측 강화: 현재
logger.warn은 파일명만 남기므로, scenemapper 가 남긴 마지막Grid map ...warn 과 상관관계를 확인하려면 grep/조인이 필요하다. 실패 직전에RefinementService::copyAlignmentToEfs | results file list - ...(line 344, debug 레벨) 를 warn 또는 info 로 승격하거나, 실패 시점에 결과 디렉토리의 파일 목록/사이즈를 error 레벨로 함께 출력하면 "산출물이 하나도 없음 vs 하나만 없음" 을 로그만으로 구분할 수 있다.
- 관측 강화: 현재
- 대상 파일:
applications/agents/packages/cupix-capture-refinement-agent/src/refinement-service.ts:378-382- 에러 코드 세분화: 현재
RefinerNotFoundInputFiles코드는checkInputFiles(입력 부재) 와copyAlignmentToEfs(산출물 부재) 두 상황에 동시에 쓰이고 있다 (:150,:380,:426). 산출물 부재는 별도 코드(예:RefinerNoRefinementOutput) 로 분리해 downstream(teslaAPI) 이 재시도/스킵 정책을 다르게 적용할 수 있게 한다.
- 에러 코드 세분화: 현재
- 대상 파일:
applications/agents/packages/cupix-capture-refinement-agent/src/manager/scenemapper.manager.ts— child process 종료 코드 및 stdout tail 을 error 레벨로 캡처해 "정상 종료했지만 산출물 없음" 케이스의 원인(예: grid map 미생성) 을 사후 분석 가능하도록 개선.
장기 개선 (재발 방지)#
- Scenemapper 알고리즘 팀과 조율하여 "grid map 미확보 → refinement 미생성" 시나리오가 정상 결과인지 이상 상태인지 판정 기준을 정의. 정상 결과라면 agent 는
throw대신 job 을no_refinement_available로 종료하도록 정책 변경. - 재발성 패턴이므로 Datadog 모니터를 도입해 24h 동안 이 에러가 임계치(예: 5건) 초과 시 clark-vdc 팀과 3D reconstruction owner 에게 알림.
Monitoring#
REQUIRED SUB-SKILL: writing-datadog-monitoring-queries 규칙에 따라 timeseries widget 에 직접 사용 가능한 형태로 작성 (pipe/stats/count by 미사용).
- 이 특정 에러의 발생 빈도 추이:
service:cupixworks-capture-refinement-arm-instance @environment:production "not found refined align_preview_meta_refinement_with_prior_map.json"
- 선행 warn (grid map) 상관관계 관측:
service:cupixworks-capture-refinement-arm-instance @environment:production "Grid map is not available or empty"
- 서비스 전반의 에러 볼륨(회귀 감지용):
service:cupixworks-capture-refinement-arm-instance status:error @environment:production
- 관련된 scenemapper child process 크래시 관측:
service:cupixworks-capture-refinement-arm-instance @environment:production "Process killed by signal SIGSEGV"
Risk Assessment#
- Risk level: medium — 클러스터 자체는 2건이지만 동일 에러가 최근 이틀 동안 여러 번 재발 중이며, 실패한 캡처는 후속 3D reconstruction 파이프라인이 진행되지 않아 사용자 산출물 지연으로 이어질 수 있다.
- 예상 복잡도: standard — 로깅/에러코드 세분화는 pure-code 변경이며 refinement-service 파일 국지적 수정으로 가능. 다만 "throw 를 유지할지 partial success 로 완화할지" 정책 결정은 알고리즘/제품 팀 조율이 필요하므로 자동 code-fix 범위 밖으로 분류한다.