ES /docs

DerivativesApi unsupported region maps to undefined URL

RCA: BaseService::handlingMessageErrors - Forge API Thumbnail 404

Overview#

What Happened#

2026-05-08 01:17~01:48 UTC 동안 cupixworks-any-thumbnail-agent 서비스에서 Autodesk Forge Model Derivative API로 BIM 썸네일 다운로드 요청 시 404 에러가 발생했다. API 요청 URL에 undefined가 포함되어 잘못된 경로로 요청이 전송되었으며, SQS 메시지가 최대 재시도 횟수(10회)에 도달한 후 삭제되면서 error 상태로 기록되었다.

Quick Facts#

Field Value
exception.class AxiosError
exception.message Request failed with status code 404
top_frame cpbim.ts:79 (catch block in downloadOriginal)
env production, ap-southeast-2

Affected Teams#

Team / Domain Error Count Impact
fluor (team_id: 142) 4 BIM 썸네일 생성 실패, BIM 모델 error 상태 전환

Timeline#

  1. 2026-05-08T01:17:36Z — 최초 에러 발생 (BIM ID 2976, user 5091)
  2. 2026-05-08T01:18:34Z — 동일 메시지 ApproximateReceiveCount=10 도달, SQS 메시지 삭제
  3. 2026-05-08T01:48:46Z — 마지막 에러 발생 (3건 추가 BIM 모델)
  4. 2026-05-08 — Error Sweeper가 클러스터 감지

Error Log#

Datadog Logs

text
BaseService::handlingMessageErrors | Error and message object - {"sqsMessage":{"MessageId":"18a53bf8-3eb3-4dd6-ab86-e1cd4b9bdb00","Attributes":{"ApproximateReceiveCount":"10"}}}

Impact#

  • Service: cupixworks-any-thumbnail-agent
  • 발생 횟수: 4 (10건 이상의 관련 로그 — 각 메시지가 10회 재시도)
  • 최초 발생: 2026-05-08T01:18:34.621Z
  • 최근 발생: 2026-05-08T01:48:46.768Z

Root Cause Summary#

forge-apis 라이브러리 (v0.9.10/v0.9.12)의 DerivativesApi가 BIM 모델의 forge_region 값을 URL 경로 prefix로 변환할 때, 지원하지 않는 region 값(ANZ/APAC 등)을 받으면 내부 region-to-path 매핑에서 undefined를 반환한다. 이로 인해 https://developer.api.autodesk.com/undefined/designdata/{urn}/thumbnail 형태의 잘못된 URL이 생성되어 Autodesk API에서 404를 반환한다. 정상적인 URL은 https://developer.api.autodesk.com/modelderivative/v2/designdata/{urn}/thumbnail (US region) 이어야 한다.

Technical Analysis#

Code Path#

  • Entry point: base-service.ts:108runByMessages() 호출
  • thumbnail-service.tscpbim.ts:20 (setModel) — BIM 데이터 로드 및 Forge 인증
  • cpbim.ts:45 (downloadOriginal) — 썸네일 다운로드 시작
  • cpbim.ts:48forgeRegion 결정
  • cpbim.ts:59-61DerivativesApi 인스턴스 생성 (region 전달)
  • cpbim.ts:68getThumbnail() API 호출
  • Failure point: cpbim.ts:78-79 — 404 에러 catch
  • base-service.ts:290handlingMessageErrors 호출
  • base-service.ts:285receiveCount >= MaxReceiveCount(10) 판정 → 메시지 삭제
packages/cupix-tesla-thumbnail-agent/src/model/cpbim.ts:45-81typescript
downloadOriginal = (): Promise<void> => new Promise((resolve, reject) => {
    const serverModel = this._serverModel;
    const forgeUrn = serverModel && (<any>serverModel).forge_urn;
    const forgeRegion = serverModel && (<any>serverModel).forge_region ? serverModel.forge_region : Environment.ADF_REGION;
    // ...
    const derivativesApi = new FORGE.DerivativesApi(
        undefined, forgeRegion
    );
    // ...
    derivativesApi.getThumbnail(forgeUrn, { width: 400, height: 400}, this._oAuth2TwoLegged, this._oAuth2TwoLegged.getCredentials())
        .then(res => { /* ... */ })
        .catch(ec => {
            logger.error('CPBim::downloadOriginal | end - %s', JSON.stringify(ec));
            reject(ec);
        });
});

forge-apis 라이브러리 내부에서 region 값을 API base path로 변환하는 매핑:

  • "US""modelderivative/v2" (정상 동작)
  • "EMEA""modelderivative/v2/regions/eu" (정상 동작)
  • 기타 값 → undefined (매핑 실패)
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에서 AxiosError의 responseundefined이므로 (error.response가 없음 — AxiosError의 config에만 정보가 있음) 빈 객체 {}가 warn 로그로 출력되었고, checkReceiveCountToDeleteMessage()receiveCount(10) >= MaxReceiveCount(10) 조건으로 true를 반환하여 메시지가 삭제되었다.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-any-thumbnail-agent status:error "CPBim::downloadOriginal"

핵심 에러 로그 — 잘못된 URL 확인:

json
{
  "message": "CPBim::downloadOriginal | end - {\"message\":\"Request failed with status code 404\",\"name\":\"AxiosError\",\"config\":{\"method\":\"get\",\"url\":\"https://developer.api.autodesk.com/undefined/designdata/dXJuOmFkc2sud2lwcHJvZGFuejpmcy5maWxlOnZmLnNwQUdnVFduUnR1M2RYbWJPRW9jZ2c_dmVyc2lvbj04/thumbnail\",\"params\":{\"width\":\"400\",\"height\":\"400\"}},\"code\":\"ERR_BAD_REQUEST\",\"status\":404}",
  "timestamp": "2026-05-08T01:48:46.740Z",
  "meta": {"Bim": {"id": 2976}, "team": {"domain": "fluor", "id": 142}, "user": {"id": 5091}}
}

URL에서 /undefined/designdata/ 부분이 핵심 증거: modelderivative/v2 대신 undefined가 삽입됨.

에러 직전 warn 로그 — getApiErrorToDeleteMessage 빈 응답:

text
BaseService::getApiErrorToDeleteMessage | error msg - {}

에러 직후 info 로그 — 메시지 삭제 확인:

text
AwsQueueManager::deleteMessage | begin - queue url: https://sqs.ap-southeast-2.amazonaws.com/002596530511/cupix-tesla-thumbnail-agent-production
AwsQueueManager::deleteMessage | end - message id: aacbb970-61cc-4efe-9635-ce7173059645

다양한 URN prefix 확인 (모두 동일한 /undefined/ 경로 패턴):

  • dXJuOmFkc2sud2lwcHJvZGFuegurn:adsk.wiprodanz (ANZ region)
  • dXJuOmFkc2sud2lwczVqa3Uurn:adsk.wips5jku
  • dXJuOmFkc2sud2lwczl2a2Qurn:adsk.wips9vkd
  • dXJuOmFkc2sud2lwczJuZmwurn:adsk.wips2nfl
  • dXJuOmFkc2sud2lwc2EzZjcurn:adsk.wipsa3f7
  • dXJuOmFkc2sud2lwczdid2Murn:adsk.wips7bwc

이 URN들은 Autodesk의 다양한 region shard에 존재하는 파일들이며, forge-apis 라이브러리가 해당 region을 URL prefix로 변환하지 못하는 것이 공통 원인이다.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 forge-apis 라이브러리가 BIM의 forge_region 값을 URL prefix로 변환 시 지원하지 않는 region 값에 대해 undefined를 반환 모든 에러 URL이 /undefined/designdata/ 패턴. 에러가 ap-southeast-2 region에서만 발생. 다양한 URN(다양한 region shard)에서 동일한 undefined path 발생 Confirmed
H2 BIM 모델의 forge_region 필드가 DB에서 null/undefined로 저장됨 코드에서 serverModel.forge_region ? ... : Environment.ADF_REGION 패턴으로 fallback 있음 fallback이 'US'(DefaultAdfRegion)이므로 undefined인 경우 US로 정상 동작해야 함. 또한 다른 agent(mesh, room)에서는 같은 패턴으로 문제 없음 Rejected
H3 Autodesk API 자체의 일시적 장애 (404) 404 status code URL 경로 자체가 /undefined/...로 잘못되어 있어 API endpoint에 도달하기 전에 404 반환. 인증은 성공(Bearer token 획득 완료) Rejected
H4 forge-apis 라이브러리 버전 간 호환성 문제 (v0.9.10 vs v0.9.12 병존) 에러 로그에서 forge-apis/0.9.10forge-apis/0.9.12 두 버전이 확인됨 두 버전 모두 동일하게 /undefined/ URL을 생성하므로 버전 차이가 아닌 근본적인 region 매핑 누락 Rejected

Fix Recommendation#

즉시 조치 (Critical)#

  • packages/cupix-tesla-thumbnail-agent/src/model/cpbim.ts:59-61DerivativesApi 생성 시 region 값을 forge-apis가 지원하는 값("US" 또는 "EMEA")으로 매핑하는 로직 추가
  • 또는 cpbim.ts:48에서 forgeRegion 값이 인식되지 않는 경우(US/EMEA 이외) "US"로 fallback하는 방어 로직 추가
  • 실패한 BIM 모델(ID: 2976 등)의 error 상태를 수동으로 복구하여 재처리 가능하도록 조치

단기 개선 (1주 이내)#

  • @cupix/forge-utils 또는 공통 유틸리티에 region 매핑 함수를 추가하여 forge-apis가 지원하지 않는 region(APAC/ANZ 등)을 적절한 값으로 변환
  • 각 agent(thumbnail, mesh, room, forge, bim-revision)에서 동일한 매핑 로직을 사용하도록 통일
  • AxiosError에서 잘못된 URL이 감지될 때 구체적인 에러 메시지를 로그에 남기도록 downloadOriginal의 catch 블록 개선

장기 개선 (재발 방지)#

  • forge-apis 라이브러리를 Autodesk Platform Services (APS)의 최신 SDK로 마이그레이션 — 최신 SDK는 APAC region을 공식 지원
  • SQS 메시지 재시도 시 영구적으로 실패할 요청(잘못된 URL 구성 등)을 조기에 식별하여 불필요한 재시도를 방지하는 circuit breaker 패턴 도입

Monitoring#

  • Forge API 호출 URL에 /undefined/ 패턴이 포함된 경우를 감지하는 알림 추가
  • 쿼리 예시:
text
service:cupixworks-any-thumbnail-agent "developer.api.autodesk.com/undefined"
  • ApproximateReceiveCount >= MaxReceiveCount 도달 빈도 모니터링

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: standard — region 매핑 로직 추가 필요, 영향 범위는 ap-southeast-2 region의 thumbnail agent에 한정