ForgeAgents - Error: { code: 305, message: Failed to load geometries for 99d37c96-d1f6-e2c4-b000-001
RCA: ForgeAgents - Failed to load geometries (code 305)
Error Log#
text
ForgeAgents - Error: { code: 305, message: Failed to load geometries for 99d37c96-d1f6-e2c4-b000-0014b473df40 }
Impact#
- Service:
cupixworks-any-room-agent - 발생 횟수: 1
- 최초 발생: 2026-04-08T10:43:27.463Z
- 최근 발생: 2026-04-08T10:43:27.463Z
Root Cause Summary#
cupix-tesla-room-agent가 BIM ID 134의 SVF2 모델(URN 99d37c96-d1f6-e2c4-b000-0014b473df40)에서 room 정보를 추출하려 할 때, @cupix/forge-agents 라이브러리의 extract() 함수가 geometry 데이터를 로드하지 못하고 error code 305 (FORGE_SOURCE_FAILED_TO_LOAD_GEOMETRIES)를 반환했다. room-extractor.process.ts의 에러 핸들링 로직은 FORGE_SOURCE_INVALID_MANIFEST (코드 202)만 SVF1 fallback으로 처리하고, 305를 포함한 나머지 에러 코드는 모두 generic Error('Failed to get rooms from svf2')로 throw한다. 이로 인해 해당 BIM의 room 추출이 실패하고 room state가 Error로 설정되었다. Geometry 로드 실패의 근본 원인은 Autodesk Platform Services(APS) 측에서 해당 모델의 geometry 리소스가 일시적으로 사용 불가했거나, 모델 변환(translation)이 불완전한 상태였을 가능성이 있다.
Technical Analysis#
Code Path#
- Entry point:
base-service.ts:107—BaseService.runByMessages()에서 SQS 메시지 처리 시작 room-service.ts:58-68—RoomService.run()이 BIM ID 134로 실행되며,runRoomExtractor()를 호출room-service.ts:187-195—runRoomExtractor()가RoomExtractManager.execute()에 Forge API 인증 정보, URN, format type(svf2), region을 전달
typescript
// room-service.ts:187-195
const roomExtractorResults = await this.roomExtractManager.execute({
apiConfig: {
clientId: Environment.ADF_CLIENT_ID,
clientSecret: Environment.ADF_CLIENT_SECRET,
},
urn: cpBim.forgeUrn,
formatType: cpBim.forgeFormatType,
region: cpBim.forgeRegion
});
room-extract.manager.ts:29—ChildProcessManager를 통해 child process로room-extractor.process.ts를 실행- Failure point:
room-extractor.process.ts:39-52—ForgeAgent.extract()가{ Error: 305 }결과를 반환하고, 이 에러 코드는FORGE_SOURCE_INVALID_MANIFEST가 아니므로 else 분기에서 generic error를 throw
typescript
// room-extractor.process.ts:39-52
if (params.formatType === 'svf2') {
const result = await ForgeAgent.extract(params.apiConfig, params.urn, {
extractRoom: true,
extractMeta: true,
region: params.region
});
if (result.Error == undefined) {
extract = result;
} else if (result.Error === ForgeAgentErrorCode.FORGE_SOURCE_INVALID_MANIFEST) {
this.log('RoomExtractorProcess::execute - svf2 manifest is invalid, try svf1 process');
extract = await RoomExtractor.room_extract(params.token, params.urn);
} else {
throw new Error('Failed to get rooms from svf2'); // ← 305 에러가 여기서 catch됨
}
}
base-service.ts:109-110— throw된 Error가BaseService.checkingQueue()의 catch 블록에서handlingMessageErrors()로 전달base-service.ts:249-252—getApiErrorToDeleteMessage()가 Error 객체에.response속성이 없으므로'undefined response'를 반환base-service.ts:301-304—'undefined response'(truthy)로 인해 SQS 메시지 삭제 및updateErrorState()호출
typescript
// base-service.ts:290-312
private handlingMessageErrors = async (error: any): Promise<void> => {
const errorAndMessage = { error: error, sqsMessage: {} };
if (this.messageInProcess) {
errorAndMessage.sqsMessage = {
MessageId: this.messageInProcess.MessageId,
Attributes: this.messageInProcess.Attributes
};
const apiErrorObject = this.getApiErrorToDeleteMessage(error);
if (apiErrorObject != undefined || this.checkReceiveCountToDeleteMessage()) {
// ... SQS 메시지 삭제 + updateErrorState() 호출
}
}
logger.error('BaseService::handlingMessageErrors | Error and message object - %s', ...);
};
Log Evidence#
사용한 Datadog 쿼리:
text
service:cupixworks-any-room-agent from:2026-04-08T09:30:00Z to:2026-04-08T11:00:00Z
text
service:cupixworks-any-room-agent status:error "Failed to load geometries" from:2026-04-08T09:30:00Z to:2026-04-08T11:30:00Z
타임라인 (KST):
| 시간 | 레벨 | 메시지 |
|---|---|---|
| 19:37:57 | info | CupixAuth::setSession | session_id: be13eccc0c1f7481a529fa1a8d872dd90a0ea81c |
| 19:37:57 | info | BaseService::runByMessage | id: 134 |
| 19:43:27 | error | Failed to use geometries: Failed to load geometries for 99d37c96-d1f6-e2c4-b000-0014b473df40 |
| 19:43:27 | warn | Failed to get rooms from svf2 |
| 19:43:27 | error | ForgeAgents - Error: { code: 305, message: Failed to load geometries for 99d37c96-d1f6-e2c4-b000-0014b473df40 } |
| 19:43:27 | error | BaseService::handlingMessageErrors | Error and message object - {"error":"undefined response","sqsMessage":{"MessageId":"ccd05145-cf56-4373-a5cc-29f49bb67d2e","Attributes":{"ApproximateReceiveCount":"1"}}} |
| 19:43:27 | info | AwsQueueManager::deleteMessage | begin - queue url: https://sqs.ap-southeast-1.amazonaws.com/.../cupix-tesla-room-agent-production |
| 19:43:27 | info | AwsQueueManager::deleteMessage | end - message id: ccd05145-cf56-4373-a5cc-29f49bb67d2e |
주요 관찰:
- BIM ID 134 처리 시작(19:37:57)부터 에러 발생(19:43:27)까지 약 5분 30초 소요 —
ForgeAgent.extract()가 geometry 로드를 시도하다가 실패한 것으로 보임 ApproximateReceiveCount가1이므로 첫 번째 시도에서 바로 실패getApiErrorToDeleteMessage()가'undefined response'를 반환하여 SQS 메시지가 재시도 없이 즉시 삭제됨@cupix/forge-agents라이브러리가 "Failed to use geometries"와 "ForgeAgents - Error" 두 개의 error 로그를 직접 출력 — 이는 라이브러리 내부에서 geometry 로딩 실패를 감지하고 error code 305로 결과를 반환하기 전에 로깅한 것
Fix Recommendation#
즉시 조치 (Critical)#
- 파일:
packages/cupix-tesla-room-agent/src/process/room-extractor.process.ts:46-52 - 현재
result.Error가FORGE_SOURCE_INVALID_MANIFEST가 아닌 모든 경우를 동일하게 throw하고 있음. Error code 305 (FORGE_SOURCE_FAILED_TO_LOAD_GEOMETRIES)와 같은 일시적 오류의 경우, SVF1 fallback을 시도하거나, 에러 코드를 포함한 구체적인 에러 메시지를 throw하여 상위에서 적절한 재시도 판단이 가능하도록 해야 함 base-service.ts:249-252에서Error객체(.response없음)가'undefined response'로 분류되어 SQS 메시지가 즉시 삭제됨. Forge 라이브러리에서 발생한 에러는 일시적일 수 있으므로, 이 경우 메시지를 삭제하지 않고 SQS visibility timeout을 통한 자연적 재시도가 이루어지도록 해야 함
단기 개선 (1주 이내)#
room-extractor.process.ts의 에러 핸들링을 error code별로 분류:- 301-306 범위의
SOURCE_LOAD에러 중 일부(예: 303FAILED_TO_LOAD_FRAGMENTS, 305FAILED_TO_LOAD_GEOMETRIES)는 SVF1 fallback을 시도 - API 서버 에러(101-107 범위)는 재시도 가능하도록 에러를 상위로 전파하되, SQS 메시지를 삭제하지 않음
- 301-306 범위의
- throw하는 Error에 원본 error code를 포함하여
BaseService.handlingMessageErrors()에서 재시도 여부를 판단할 수 있도록 개선
장기 개선 (재발 방지)#
BaseService.getApiErrorToDeleteMessage()의 에러 분류 로직 개선: Forge 라이브러리 에러와 API 응답 에러를 구분하여, 일시적 Forge 에러에 대해 SQS 재시도 메커니즘을 활용@cupix/forge-agents라이브러리의 error code enum을 room-agent 패키지에서 활용하여 세분화된 에러 핸들링 구현- APS(Autodesk) 모델 상태를 geometry 추출 전에 확인하는 pre-check 로직 추가 고려
Monitoring#
- Forge error code별 발생 빈도 추적:
text
service:cupixworks-any-room-agent "ForgeAgents - Error" | pattern("code: %{integer:forge_error_code}")
- Geometry 로드 실패 알림:
text
service:cupixworks-any-room-agent status:error "Failed to load geometries"
- SQS 메시지가 재시도 없이 삭제되는 경우 감지:
text
service:cupixworks-any-room-agent "undefined response" "ApproximateReceiveCount\":\"1\""
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 단일 BIM 모델에 대한 단발성 이벤트. 다른 BIM 모델(ID 133, 18933)은 동시간대에 정상 처리됨 (로그에서
importRoomsFromBim,createBimRooms성공 확인). 다만, 현재 에러 핸들링 구조에서는 일시적 Forge 에러도 재시도 없이 최종 실패로 처리되므로, 동일 패턴이 반복될 가능성이 있음.