ForgeAgent off-by-one error accessing invalid object ID in SVF2
RCA: ForgeAgents - Error: { code: 1, message: Failed to get properties and children }
Error Log#
ForgeAgents - Error: { code: 1, message: Failed to get properties and children }
Impact#
- Service:
cupixworks-any-room-agent - 발생 횟수: 1
- 최초 발생: 2026-04-09T06:44:25.133Z
- 최근 발생: 2026-04-09T06:44:25.133Z
Root Cause Summary#
BIM ID 18949의 SVF2 모델 property database를 순회하는 과정에서 @cupix/forge-agents 라이브러리가 유효하지 않은 object ID 759923에 접근을 시도했습니다 (유효 범위: 1~759922). 이 off-by-one 에러는 라이브러리 내부에서 발생하며, RoomExtractorProcess.execute()에서 ForgeAgent.extract() 호출 결과의 result.Error 값이 ForgeAgentErrorCode.FORGE_SOURCE_INVALID_MANIFEST가 아닌 다른 에러 코드(code: 1)로 반환되었기 때문에 SVF1 fallback 없이 "Failed to get rooms from svf2" 예외가 throw되었습니다. 이 에러는 해당 BIM 모델 파일의 property database가 손상되었거나, 노드 참조가 실제 데이터 범위를 초과하는 경우에 발생합니다.
Technical Analysis#
Code Path#
- Entry point:
BaseService.checkingQueue()— SQS 메시지 수신 후runByMessages()호출 (base-service.ts:107-108) BaseService.runByMessage()— 메시지 파싱 후this.run(targetId)호출 (base-service.ts:170)RoomService.run()— BIM 객체 생성 후runRoomExtractor(cpBim)호출 (room-service.ts:68)RoomService.runRoomExtractor()—RoomExtractManager.execute()호출 (room-service.ts:187)RoomExtractManager.execute()— child process로 IPC 메시지 전달 (room-extract.manager.ts:29)RoomExtractorProcess.execute()—ForgeAgent.extract()호출, 결과의 Error 필드 검사 (room-extractor.process.ts:40-53)- Failure point:
room-extractor.process.ts:52—result.Error가FORGE_SOURCE_INVALID_MANIFEST가 아니므로 catch-all throw 실행
// packages/cupix-tesla-room-agent/src/process/room-extractor.process.ts:39-53
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'); // <-- 여기서 throw
}
}
ForgeAgent.extract()가 { code: 1, message: "Failed to get properties and children" } 에러를 반환했으나, 이 에러 코드는 FORGE_SOURCE_INVALID_MANIFEST와 일치하지 않습니다. 현재 코드는 manifest invalid 에러만 SVF1 fallback으로 처리하고, 그 외 모든 에러는 동일하게 throw합니다.
에러 전파 경로:
// packages/base/src/manager/child-process.manager.ts:179-183
if (response.success) {
pending.resolve(response.data);
} else {
pending.reject(new Error(response.error || 'Unknown error')); // IPC 에러 전파
}
// packages/base/src/base-service.ts:107-111
try {
await this.runByMessages();
} catch (error) {
await this.handlingMessageErrors(error); // 최종 에러 핸들링
}
// packages/base/src/base-service.ts:290-313
private handlingMessageErrors = async (error: any): Promise<void> => {
const errorAndMessage = { error: error, sqsMessage: {} };
if (this.messageInProcess) {
// ...
const apiErrorObject = this.getApiErrorToDeleteMessage(error);
if (apiErrorObject != undefined || this.checkReceiveCountToDeleteMessage()) {
await this.deleteByMessage(this.messageInProcess);
if (this._modelInProcess != undefined) await this.updateErrorState(this._modelInProcess);
}
}
logger.error('BaseService::handlingMessageErrors | Error and message object - %s', JSON.stringify(errorAndMessage));
};
getApiErrorToDeleteMessage()에서 Error 객체는 response 프로퍼티가 없으므로 "undefined response"를 반환합니다. 이 값이 truthy이므로 SQS 메시지가 삭제되고 BIM 상태가 Error로 업데이트됩니다.
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-any-room-agent "Failed to get properties and children" status:error
service:cupixworks-any-room-agent
에러 cascade (5개 로그, 동일 밀리초 내 발생):
2026-04-09T06:44:25.132Z | ERROR | Failed to get properties and children: Invalid object ID: 759923. Valid range is 1 to 759922.
2026-04-09T06:44:25.132Z | ERROR | Failed to get node: Failed to get properties and children
2026-04-09T06:44:25.132Z | ERROR | Failed to traverse nodes: Failed to get properties and children
2026-04-09T06:44:25.133Z | ERROR | Failed to use property database: Failed to get properties and children
2026-04-09T06:44:25.133Z | ERROR | ForgeAgents - Error: { code: 1, message: Failed to get properties and children }
이후 에러 전파 로그:
2026-04-09T06:44:25.136Z | ERROR | Failed to get rooms from svf2 (bim.id: 18949, stack: Error at ChildProcessManager2.handleMessage /tmp/agent/dist/app.cjs:5213:26)
2026-04-09T06:44:25.138Z | WARN | Failed to get rooms from svf2 (bim.id: 18949)
SQS 메시지 삭제 및 최종 에러 핸들링:
2026-04-09T06:44:25.138Z | INFO | AwsQueueManager::deleteMessage | begin - queue: cupix-tesla-room-agent-production
2026-04-09T06:44:25.168Z | INFO | AwsQueueManager::deleteMessage | end - message id: 1cc77d38-fb8b-4272-bbf9-13fe1fedeb7b
{
"message": "BaseService::handlingMessageErrors | Error and message object",
"error": "undefined response",
"sqsMessage": {
"MessageId": "1cc77d38-fb8b-4272-bbf9-13fe1fedeb7b",
"Attributes": { "ApproximateReceiveCount": "1" }
}
}
영향받은 엔티티:
- BIM ID: 18949
- User: mohammed.alshaikhli@exyte.net (user.id: 39592)
- Team: exyte (team.id: 783)
- Host: ip-10-1-39-24.us-west-2.compute.internal
14일간 ForgeAgents 에러 현황: code: 1 (property database 에러)은 이번 1건이 유일합니다. 가장 빈번한 에러는 code: 305 (geometry 로드 실패)와 INVALID_OTG_ERROR (OTG pending 상태)입니다.
Fix Recommendation#
즉시 조치 (Critical)#
- 파일:
packages/cupix-tesla-room-agent/src/process/room-extractor.process.ts:46-53 result.Error처리 로직에서 property database 관련 에러(code: 1)도 SVF1 fallback 대상에 포함시키는 것을 검토해야 합니다. 현재는FORGE_SOURCE_INVALID_MANIFEST만 fallback 처리하고 그 외 에러는 모두 실패로 처리합니다. property database 순회 실패는 SVF2 파일 자체의 문제일 가능성이 높으므로, SVF1으로 재시도하면 성공할 수 있습니다.- 에러 throw 시 원본
result.Error정보(code, message)를 포함하도록 에러 메시지를 개선하면 디버깅이 용이해집니다.
단기 개선 (1주 이내)#
- SVF1 fallback 대상 에러 코드를 화이트리스트가 아닌 블랙리스트 방식으로 전환하는 것을 검토합니다. 즉, fallback이 불가능한 에러만 명시적으로 제외하고, 나머지 에러는 모두 SVF1 fallback을 시도하도록 합니다.
bim-revision-agent의ForgeErrorMapper패턴을 참고하여, room-agent에서도 에러 코드별 처리 전략을 체계화합니다.
장기 개선 (재발 방지)#
@cupix/forge-agents라이브러리 내부에서 property database 순회 시 object ID 범위 검증을 강화하여, off-by-one 에러가 발생하지 않도록 합니다.- SVF2 모델 파일의 무결성 검증 단계를 extraction 전에 추가하여, 손상된 모델에 대해 조기 감지 및 적절한 에러 코드 반환이 가능하도록 합니다.
Monitoring#
- 추가할 메트릭: ForgeAgents 에러를 error code별로 분류하여 추적
- Datadog 쿼리 예시:
service:cupixworks-any-room-agent "ForgeAgents - Error" status:error @environment:production
service:cupixworks-any-room-agent "Failed to get rooms from svf2" status:error @environment:production
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 14일간 동일 에러 코드(
code: 1) 발생은 이번 1건이 유일하며, 특정 BIM 모델(ID 18949)의 property database 문제로 한정됩니다. 사용자 영향은 해당 BIM의 room extraction 실패로 제한되며, 에러 발생 후 BIM 상태가 Error로 업데이트되고 다음 메시지 처리는 정상 진행되었습니다.