ES /docs

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#

  1. 2026-04-23T19:46:13Z — SQS 메시지 수신, BIM ID 19176 처리 시작 (BaseService::runByMessage)
  2. 2026-04-23T19:46:14Z — Cupix API 인증 세션 생성
  3. 2026-04-23T19:46:15ZRoomExtractManager::execute 시작 (SVF2 format으로 Forge extraction)
  4. 2026-04-23T19:46:18Z — Forge property database traversal 중 object ID 9217 조회 실패, 에러 체인 전파
  5. 2026-04-23T19:46:18ZBaseService::handlingMessageErrors에서 SQS 메시지 삭제 처리

Error Log#

Datadog Logs

text
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:58run() 메서드에서 BIM ID 19176으로 처리 시작
  • room-service.ts:68runRoomExtractor(cpBim) 호출
packages/cupix-tesla-room-agent/src/room-service.ts:58-68typescript
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-196RoomExtractManager.execute()에 URN과 format type 전달
packages/cupix-tesla-room-agent/src/room-service.ts:187-196typescript
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로 실행 위임
packages/cupix-tesla-room-agent/src/manager/room-extract.manager.ts:25-41typescript
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() 호출
packages/cupix-tesla-room-agent/src/process/room-extractor.process.ts:39-53typescript
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)

packages/base/src/base-service.ts:290-313typescript
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 쿼리:

text
service:cupixworks-any-room-agent status:error "Failed to get properties and children"
text
service:cupixworks-any-room-agent "Invalid object ID" status:error

에러 발생 시점의 전체 로그 체인 (bottom-up, 동일 타임스탬프 2026-04-23T19:46:18Z):

text
Failed to get properties and children: Invalid object ID: 9217. Valid range is 1 to 9216.
text
Failed to get node: Failed to get properties and children
text
Failed to use property database: Failed to get properties and children
text
Failed to traverse nodes: Failed to get properties and children
text
ForgeAgents - Error: { code: 1, message: Failed to get properties and children }
text
BaseService::handlingMessageErrors | Error and message object - {"error":"undefined error","sqsMessage":{"MessageId":"23bb29ea-16f7-4adf-bbb2-8d3b38a34d42","Attributes":{"ApproximateReceiveCount":"1"}}}

에러 전 처리 컨텍스트 (info 레벨):

text
[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일간 동일 패턴 검색 결과 — 다양한 모델에서 반복 발생:

text
[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 값. 에러 체인이 getPropertiesAndChildrenget nodetraverse nodesuse 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.Errorundefined가 아니고 FORGE_SOURCE_INVALID_MANIFEST도 아닌 경우 generic throw 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#

추가할 메트릭/알림:

text
service:cupixworks-any-room-agent status:error "Invalid object ID"
  • 위 쿼리를 Datadog 모니터로 등록하여, 동일 패턴 발생 빈도 추적
  • @cupix/forge-agents 업그레이드 후 발생 횟수 감소 여부 확인
text
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차 대응이며, 내부 에러 핸들링 개선은 표준 난이도.