Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216.
RCA: Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216.
Overview#
What Happened#
2026-04-23T19:46:18Z에 cupixworks-any-room-agent 서비스에서 BIM ID 19176 (Revit 파일 HLC_HB.rvt)의 room extraction 처리 중 Autodesk Forge property database 조회가 실패했다. @cupix/forge-agents 라이브러리가 object ID 9217을 조회하려 했으나, 해당 모델의 property database에는 1~9216 범위의 object만 존재하여 out-of-range 오류가 발생했다.
Quick Facts#
| Field | Value |
|---|---|
| exception.message | Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216. |
| top_frame | @cupix/forge-agents (내부 property database traversal) |
| env | production, us-west-2 |
| BIM ID | 19176 |
| Forge URN | urn:adsk.objects:os.object:tesla-production/19176_1776972884833_HLC_HB.rvt |
Timeline#
- 2026-04-23T19:46:13Z — SQS 메시지 수신, BIM ID 19176 처리 시작 (
BaseService::runByMessage) - 2026-04-23T19:46:14Z — Cupix API 인증 세션 생성
- 2026-04-23T19:46:15Z —
RoomExtractManager::execute시작 (SVF2 format으로 Forge extraction) - 2026-04-23T19:46:18Z — Forge property database traversal 중 object ID 9217 조회 실패, 에러 체인 전파
- 2026-04-23T19:46:18Z —
BaseService::handlingMessageErrors에서 SQS 메시지 삭제 처리
Error Log#
Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216.
Impact#
- Service:
cupixworks-any-room-agent - 발생 횟수: 1 (이번 클러스터), 14일간 동일 패턴 5건 (다른 모델 포함)
- 최초 발생: 2026-04-23T19:46:18.200Z
- 최근 발생: 2026-04-23T19:46:18.200Z
- 사용자 영향: BIM 모델 19176의 room extraction이 실패하고 BIM room_state가
error로 전환됨. 해당 시설의 room 기반 기능(workarea, room 매칭)이 작동하지 않음. SQS 메시지는 삭제되어 자동 재시도 없음.
Root Cause Summary#
@cupix/forge-agents@10.16.0 라이브러리가 Autodesk Forge SVF2 property database를 traverse할 때, 모델의 실제 object 수(9216개)보다 1 큰 ID(9217)를 조회하여 out-of-range 오류가 발생했다. 이는 @cupix/forge-agents 내부의 node traversal 로직이 property database의 object 수 경계를 정확히 처리하지 못하는 off-by-one 버그로 추정된다. 14일간의 로그를 보면 동일 패턴이 다양한 모델에서 반복 발생하며(ID가 valid range보다 항상 1~2 초과), 특정 모델 구조에서 재현되는 체계적 문제이다.
Technical Analysis#
Code Path#
- Entry point:
room-service.ts:58—run()메서드에서 BIM ID 19176으로 처리 시작 room-service.ts:68—runRoomExtractor(cpBim)호출
protected run = async (targetId: number): Promise<void> => {
const cpBim = await this.createCPBimByBimId(targetId);
if (cpBim) {
this._modelInProcess = cpBim;
this._forgeApi.updateRegionFromBim(cpBim.forgeRegion);
if (cpBim.workspaceDirPath) this.setModelWorkspace(cpBim.workspaceDirPath);
if (cpBim.isGenerateMasterViews) {
await this.forgeAuth.authenticate();
await this.updateBimRoomState(targetId, TESLA.UpdateBimRequest.RoomStateEnum.Extracting);
await this.runRoomExtractor(cpBim);
room-service.ts:187-196—RoomExtractManager.execute()에 URN과 format type 전달
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— child process로 실행 위임
async execute(params: RoomExtractorParams): Promise<RoomExtractorResults> {
logger.debug('RoomExtractManager::execute | begin with urn:', params.urn);
try {
const result = await this.childProcessManager.execute<RoomExtractorResults>('execute', params);
logger.debug('RoomExtractManager::execute | completed successfully');
return result;
} catch (error) {
logger.error('RoomExtractManager::execute | error:', error);
const errorCode = ErrorCode.Agent.RoomExtractorExecute;
if (this.setJobErrorCode) {
this.setJobErrorCode(errorCode);
}
throw error;
}
}
room-extractor.process.ts:39-44— SVF2 format이므로ForgeAgent.extract()호출
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');
}
-
Failure point:
@cupix/forge-agents@10.16.0내부 — property database node traversal 중 object ID 9217 접근 시 out-of-range 발생 -
ForgeAgent.extract()내부에서 SVF2 property database를 로드하고 모든 node를 순회하면서 room 정보를 추출하는 과정에서, 총 9216개 object가 있는 모델에서 ID 9217을 조회하려 함 -
Error propagation:
@cupix/forge-agents→ child process (room-extractor.process.ts:66-75) →RoomExtractManager(room-extract.manager.ts:32-41) →RoomService.run()→BaseService.handlingMessageErrors()(base-service.ts:290-313)
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()) {
try {
errorAndMessage.error = apiErrorObject;
await this.deleteByMessage(this.messageInProcess);
if (this._modelInProcess != undefined && this._modelInProcess.id > 0) await this.updateErrorState(this._modelInProcess);
} catch (error) {
logger.error('BaseService::handlingMessageErrors | Errors in error handling', error);
}
}
}
logger.error('BaseService::handlingMessageErrors | Error and message object - %s', JSON.stringify(errorAndMessage));
};
getApiErrorToDeleteMessage()에서 해당 에러가 API 응답이 아닌 내부 에러이므로 "undefined error"를 반환하고, 이로 인해 SQS 메시지가 삭제되며 BIM room_state가 error로 설정된다.
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-any-room-agent status:error "Failed to get properties and children"
service:cupixworks-any-room-agent "Invalid object ID" status:error
에러 발생 시점의 전체 로그 체인 (bottom-up, 동일 타임스탬프 2026-04-23T19:46:18Z):
Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216.
Failed to get node: Failed to get properties and children
Failed to use property database: Failed to get properties and children
Failed to traverse nodes: Failed to get properties and children
ForgeAgents - Error: { code: 1, message: Failed to get properties and children }
BaseService::handlingMessageErrors | Error and message object - {"error":"undefined error","sqsMessage":{"MessageId":"23bb29ea-16f7-4adf-bbb2-8d3b38a34d42","Attributes":{"ApproximateReceiveCount":"1"}}}
에러 전 처리 컨텍스트 (info 레벨):
[2026-04-23T19:46:13Z] BaseService::runByMessage | id: 19176
[2026-04-23T19:46:14Z] CupixAuth::setSession | session_id: 01f25334a39bd45ae0a78c996f2b0c743fa71c06
[2026-04-23T19:46:15Z] RoomExtractManager::execute | urn: dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dGVzbGEtcHJvZHVjdGlvbi8xOTE3Nl8xNzc2OTcyODg0ODMzX0hMQ19IQi5ydnQ=
URN 디코딩: urn:adsk.objects:os.object:tesla-production/19176_1776972884833_HLC_HB.rvt
14일간 동일 패턴 검색 결과 — 다양한 모델에서 반복 발생:
[2026-04-23T19:46:18Z] Invalid object ID: 9217. Valid range is 1 to 9216.
[2026-04-22T12:26:17Z] Invalid object ID: 9217. Valid range is 1 to 9216. (동일 모델 재시도 추정)
[2026-04-14T12:58:23Z] Invalid object ID: 1511932. Valid range is 1 to 1511930.
[2026-04-13T15:53:16Z] Invalid object ID: 4435162. Valid range is 1 to 4435158.
[2026-04-09T06:44:25Z] Invalid object ID: 759923. Valid range is 1 to 759922.
모든 케이스에서 invalid object ID가 valid range 상한보다 1~4 큰 값이다. 이는 @cupix/forge-agents 내부 traversal 로직의 off-by-one 또는 boundary 처리 버그 패턴과 일치한다.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | @cupix/forge-agents 내부 property database traversal에서 off-by-one 버그로 object 수 경계를 초과하여 접근 |
14일간 5건 모두 invalid ID가 valid range 상한+1~4 값. 에러 체인이 getPropertiesAndChildren → get node → traverse nodes → use property database 순으로 전파됨. 다양한 모델(9216, 1511930, 4435158, 759922개 object)에서 동일 패턴 |
— | Confirmed |
| H2 | Autodesk Forge API 서버 측 일시적 오류 또는 rate limiting | — | 에러 메시지가 명확한 validation 오류("Valid range is 1 to N")이며, 다양한 시간대/모델에서 반복 발생. Forge API rate limit 에러는 429 응답으로 나타나며 이 패턴과 다름 | Rejected |
| H3 | 손상된 BIM 모델 데이터 (특정 모델만 문제) | BIM ID 19176이 2회 연속 실패 (04/22, 04/23) | 다른 모델(object 수 1511930, 4435158, 759922)에서도 동일 패턴 발생. 특정 모델이 아닌 library 내부 문제 | Rejected |
| H4 | SVF2 manifest가 invalid하여 잘못된 property database가 로드됨 | SVF2 extraction 경로에서 발생 | room-extractor.process.ts:48에서 invalid manifest 케이스는 별도로 처리되어 SVF1 fallback으로 전환됨. 이 에러는 manifest는 유효하나 traversal 중 발생 |
Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
@cupix/forge-agents패키지(현재10.16.0)를 최신 버전으로 업데이트하여 off-by-one 버그가 수정되었는지 확인. 패키지 변경 로그에서 property database traversal 관련 수정 사항 확인 필요.- 파일:
packages/cupix-tesla-room-agent/package.json:29
- 파일:
단기 개선 (1주 이내)#
room-extractor.process.ts:39-53에서ForgeAgent.extract()호출 시 에러 핸들링을 보강. 현재는result.Error가undefined가 아니고FORGE_SOURCE_INVALID_MANIFEST도 아닌 경우 genericthrow new Error('Failed to get rooms from svf2')만 발생시키는데, property database traversal 실패를 별도로 분류하여 SVF1 fallback을 시도하거나 사용자에게 의미 있는 에러 코드를 전달하는 것이 좋다.BaseService.getApiErrorToDeleteMessage()(base-service.ts:240-276)에서 내부 에러를"undefined error"로 분류하는 대신,@cupix/forge-agents에러의 경우 에러 메시지를 보존하여 로그에 구체적 정보가 남도록 개선.
장기 개선 (재발 방지)#
@cupix/forge-agents라이브러리 내부에 property database traversal 시 object ID 범위 검증 로직을 추가하여, 유효 범위를 초과하는 ID에 대해 skip하고 경고를 남기는 방식으로 변경. 이를 통해 일부 object 조회 실패가 전체 room extraction을 중단시키지 않도록 한다.- room extraction 실패 시 자동 재시도 메커니즘 검토. 현재
BaseService.handlingMessageErrors()에서 에러 타입에 관계없이 SQS 메시지를 삭제하여 재시도 기회가 없어진다. Forge property database 관련 에러는 모델 자체의 문제이므로 재시도보다는 사용자에게 구체적 에러 상태를 전달하는 것이 적절할 수 있다.
Monitoring#
추가할 메트릭/알림:
service:cupixworks-any-room-agent status:error "Invalid object ID"
- 위 쿼리를 Datadog 모니터로 등록하여, 동일 패턴 발생 빈도 추적
@cupix/forge-agents업그레이드 후 발생 횟수 감소 여부 확인
service:cupixworks-any-room-agent "ForgeAgents - Error"
- Forge agent 에러 전반을 모니터링하여 패키지 안정성 추적
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 근거: 발생 빈도가 14일간 5건으로 낮고, 특정 모델의 room extraction에만 영향을 미친다. 핵심 데이터 파이프라인(capture, pano processing)에는 영향 없음. 수정은
@cupix/forge-agents패키지 업데이트가 1차 대응이며, 내부 에러 핸들링 개선은 표준 난이도.