HTTP request failed
RCA: HTTP request failed (mesh agent — trashed BIM 조회 실패)
Overview#
What Happened#
2026-07-15 15:17 KST, cupixworks-any-mesh-agent(tesla mesh agent, ap-southeast-1 / gammon-forida) 가 BIM 227 을 SQS 로 수신한 뒤 tesla API 로 조회하는 첫 단계에서 HttpError: HTTP request failed (statusCode 403, body ENT4000 Cupix::Errors::NotFound "Bim not found") 을 만나 mesh 추출 파이프라인이 실패로 처리됐다. 동일 패턴(다른 BIM ID) 이 24 시간 내 최소 3 건(1712, 1714, 229, 227) 관측되어 재발성 이슈다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | HttpError |
| exception.message | HTTP request failed |
| top_frame | @tesla/typescript-node-sdk/api/bimApi.js:1191 |
| runtime | Node.js (tesla mesh agent, pnpm bundle /tmp/agent/dist) |
| downstream | http://api-tesla.cupix.internal/api/v1/bims/{id} → 403 ENT4000 |
| env | production, region ap-southeast-1 |
Affected Teams#
| Team / Domain | Error Count | Impact |
|---|---|---|
| gammon-forida (tenant cupix, ap-southeast-1) | 1 (해당 클러스터) | BIM 227 mesh 추출 실패 → mesh_state=error 로 표시되어 downstream 서비스(3D viewer, siteinsights) 에서 mesh 를 사용할 수 없음 |
| 24h 전체 mesh-agent (같은 fingerprint 계열) | 4+ 건 (bim 227, 229, 1712, 1714) | trashed BIM 이 SQS 에 남아 있으면 매번 error 로그 발생, SQS 메시지는 삭제 처리됨 |
Timeline#
- 2026-07-14 05:34 ~ 13:44 KST — 전날
svc:cupixworks-any-mesh-agent::unknown인시던트(5 clusters, resolved) 발생. 상태 보드에 recent 로 기록됨. - 2026-07-15 15:16:15 KST — BIM 229 처리 중
createCPBimByBimId | end - reason: Bim not found(warn) — 다른 코드 경로(ARG10002) 가 정상 흡수한 케이스. - 2026-07-15 15:17:24 KST — BIM 227 처리 중 tesla API 가
403 ENT4000(trashed) 응답. mesh-service 는ENT4000을 처리하지 않아 error 로 propagate.MeshService::run | error: HTTP request failed로그 발생 (본 클러스터의 대표 로그). - 2026-07-15 15:17:24 KST —
BaseService::handlingMessageErrors가 statusCode 403 을 400 대역 규칙으로 판정하고 SQS 메시지를 삭제. workspace/tmp/workspace/227정리.
Error Log#
HTTP request failed
Datadog에서 확인한 stack 및 응답:
{
"stack": "HttpError: HTTP request failed\n at Request._callback (/tmp/agent/dist/node_modules/.pnpm/@tesla+typescript-node-sdk@1.13.3-SNAPSHOT.202605301249_1e9855b03300e7077469e8a23e5d7e36/node_modules/@tesla/typescript-node-sdk/api/bimApi.js:1191:40) ...",
"message": "HTTP request failed",
"response": { "body": {}, "statusCode": 403 },
"statusCode": 403,
"name": "HttpError"
}
동일 시점 handlingMessageErrors 페어링 로그(원문):
{
"error": {
"statusCode": 403,
"requestUriHref": "http://api-tesla.cupix.internal/api/v1/bims/227?fields[0]=id&...",
"bodyResult": {
"code": "ENT4000",
"type": "Cupix::Errors::NotFound",
"reason": "Bim not found",
"message": "Bim not found"
},
"modelId": 227
},
"sqsMessage": { "MessageId": "912c9efa-6a43-4026-b5f4-4b6e5e282a75", "Attributes": { "ApproximateReceiveCount": "1" } }
}
Impact#
- Service:
cupixworks-any-mesh-agent - Team: gammon-forida
- 발생 횟수: 1 (본 클러스터). 24h 내 동일 fingerprint 계열 4+ 건.
- 최초 발생: 2026-07-15 15:17 KST
- 최근 발생: 2026-07-15 15:17 KST
BIM 이 이미 trash 로 이동된 상태이므로 사용자 체감 영향은 제한적이지만, 매 발생마다 mesh_state=error 를 (이미 삭제된) BIM 에 기록하려는 시도가 뒤따르고 error 레벨 로그가 alerting 노이즈로 남는다.
Root Cause Summary#
Mesh agent 의 MeshService.createCPBimByBimId 는 tesla API 가 반환하는 "not found" 응답 중 code === 'ARG10002' 만 성공적으로 흡수해 resolve(undefined) 로 조용히 종료한다. 그러나 tesla BaseRepository#show 는 대상 레코드가 trash 상태일 때 ENT4000 을, 완전 부재일 때 ARG10002 를 반환한다 (app/repositories/base_repository.rb:351-356). SQS 메시지 enqueue 이후 BIM 이 소프트 삭제되면 tesla 가 403 ENT4000 을 돌려주지만, mesh agent 는 이를 whitelist 하지 않아 HttpError 로 그대로 throw → MeshService::run 의 catch 블록이 HTTP request failed 로 error 로깅. 이후 getApiErrorToDeleteMessage 가 4xx 를 SQS 에서 제거해 재시도되지 않지만, 매번 error 레벨 스택트레이스가 남는다.
Technical Analysis#
Code Path#
- Entry point:
applications/agents/packages/cupix-tesla-mesh-agent/src/mesh-service.ts:101(MeshService.run) - 첫 API 호출:
MeshService.createCPBimByBimId→this.cupixApi.bim.get(bimId)(line 134). teslaGET /api/v1/bims/{id}로 매핑. - Failure point:
mesh-service.ts:145—ENT4000이 whitelist 에 없어reject(ec)실행 - Propagation:
run의 try/catch (line 117-120) 가HTTP request failed로 error 로그 남기고updateErrorState호출
private createCPBimByBimId = (bimId: number): Promise<CPBim | undefined> => new Promise((resolve, reject) => {
logger.debug('MeshService::createCPBimByBimId | begin');
logger.debug('MeshService::createCPBimByBimId | bimId: %d', bimId);
this.cupixApi.bim.get(bimId)
.then(resBim => {
logger.debug('MeshService::createCPBimByBimId | end');
resolve(new CPBim(resBim));
})
.catch(ec => {
const body = ec?.response?.body;
if (body) {
const code = body.result?.code;
const reason = body.result?.reason ? body.result.reason : body.result?.message;
logger.warn('MeshService::createCPBimByBimId | end - reason: %s', reason);
if (code === 'ARG10002') return resolve(undefined); // ENT4000 은 처리 안 됨
}
reject(ec);
});
});
Tesla 측(downstream) 이 두 코드를 구분하는 지점:
if model.nil?
if self.where(attrs).in_trash.present?
raise Cupix::Errors::NotFound.new(code: 'ENT4000', reason: "#{current_class.name} not found")
else
raise Cupix::Errors::NotFound.new(code: 'ARG10002', reason: "#{current_class.name} not found")
end
end
기대 동작: BIM 이 trash 상태여도 mesh agent 는 warn 로그 후 조용히 skip (SQS 메시지 삭제).
실제 동작: ENT4000 이 whitelist 를 통과하지 못해 HttpError 로 rethrow → run() catch → error 레벨 로그 + updateErrorState 시도(자체적으로 다시 403 가능성).
Log Evidence#
Datadog 쿼리 (본 클러스터 재현):
service:cupixworks-any-mesh-agent status:error @environment:production "HTTP request failed"
24h 내 동일 패턴 확인:
service:cupixworks-any-mesh-agent status:error @environment:production
BIM 227 처리 시퀀스 (2026-07-15 15:17:24 KST, tight window):
15:17:24 warn CupixAuth::handleError | Response statusCode: 403, requestUriHref: .../bims/227..., body.result: {"code":"ENT4000","type":"Cupix::Errors::NotFound","reason":"Bim not found"}
15:17:24 error MeshService::run | error: {"stack":"HttpError: HTTP request failed ... bimApi.js:1191:40 ...","statusCode":403,"name":"HttpError"}
15:17:24 error HTTP request failed
15:17:24 warn BaseService::getApiErrorToDeleteMessage | error msg - {...,"modelId":227}
15:17:24 error BaseService::handlingMessageErrors | Error and message object - {...,"modelId":227,"sqsMessage":{"MessageId":"912c9efa-...","ApproximateReceiveCount":"1"}}
15:17:24 info BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/227
BIM 229 (같은 시간대, 다른 응답 경로) — ARG10002 로 조용히 종료:
15:16:15 warn MeshService::createCPBimByBimId | end - reason: Bim not found
두 로그를 비교하면 ARG10002 는 createCPBimByBimId 안에서 warn 으로 정리되지만 ENT4000 (본 클러스터) 는 상위 MeshService::run catch 까지 올라가 error 로 기록됨이 확인된다.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | Tesla API 인증 만료/토큰 문제로 403 | 403 statusCode | body.result 가 auth 오류가 아닌 Cupix::Errors::NotFound ENT4000. CupixAuth::handleError 도 body 를 그대로 통과시킴 |
Rejected |
| H2 | Tesla API 서비스 outage / 네트워크 실패 | HTTP request failed 문자열 |
statusCode 403 + 정상 JSON body 수신 → 서버가 응답한 명시적 4xx. 상태보드에도 dep:* 아님 (svc:cupixworks-any-mesh-agent::unknown) |
Rejected |
| H3 | SQS 처리 지연 중 BIM 이 trash 로 이동, mesh-service 가 ENT4000 (trashed) 를 whitelist 하지 않아 error 로 승격 |
bodyResult.code=ENT4000 type=Cupix::Errors::NotFound reason="Bim not found" modelId=227; tesla base_repository.rb:352 가 in_trash 일 때 ENT4000 반환; mesh-service mesh-service.ts:145 는 ARG10002 만 검사; 자매 로그(BIM 229) 는 ARG10002 로 warn 종료 |
— | Confirmed |
| H4 | ADF (Autodesk Forge) 관련 downstream 실패 | Forge 도 호출됨 | Stack trace 가 bimApi.js:1191 (tesla SDK) 이며 URI 는 api-tesla.cupix.internal/bims/227. Forge 호출 이전 단계 |
Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
- 파일:
applications/agents/packages/cupix-tesla-mesh-agent/src/mesh-service.ts:145 createCPBimByBimId의 catch 블록에서 whitelist 를ARG10002뿐 아니라ENT4000도 포함하도록 확장한다. 두 코드 모두 tesla 측에서Cupix::Errors::NotFound로 통일된 semantic (부재/휴지통) 이므로 agent 관점에서는 동일하게 "skip" 처리하는 것이 안전.- 같은 파일 내
updateBimMeshState(line 156-163) 호출도 이후run()의updateErrorState(line 297-302) 에서 trashed BIM 을mesh_state=error로 업데이트하려다 재차ENT4000을 만날 수 있다.updateErrorState의 catch 도 동일 whitelist 를 적용해야 error 로그 재발을 막을 수 있음.
단기 개선 (1주 이내)#
packages/api/src/authentication/cupix-auth.ts:42handleError는 현재 모든 4xx 를warn으로 남기지만 상위에서 다시error로 승격된다. tesla API 가 명시적으로Cupix::Errors::NotFoundbody 를 리턴한 경우는 agent 공통 레벨에서 warn 으로 유지하도록 매핑 규칙을 정리 (base-service.tsgetApiErrorToDeleteMessage와 함께 통일).- 다른 agent 서비스(
potree,forge,bim-revision,deviation-*) 도 동일 패턴을 공유한다면 base 레이어에TeslaNotFoundCodes = ['ARG10002', 'ENT4000']을 상수화하여 재사용.
장기 개선 (재발 방지)#
- SQS enqueue 이후 실 처리까지 시간차가 존재하는 한 "leftover trashed job" 은 지속 발생한다. tesla 측에서 BIM soft-delete 시 mesh 관련 in-flight SQS 메시지를 정리하거나, agent 가 실행 초입에서 trash 상태를 정상 종료 케이스(정보 로그 + SQS ack)로 분류하는 정책을 문서화.
Monitoring#
핵심 monitor 쿼리 (release dashboard timeseries widget 그대로 사용):
service:cupixworks-any-mesh-agent status:error @environment:production "HTTP request failed"
ENT4000 만 좁혀서 재발 여부 확인:
service:cupixworks-any-mesh-agent status:error @environment:production "ENT4000"
트레이싱용 (warn 레벨, upstream context):
service:cupixworks-any-mesh-agent status:warn @environment:production "CupixAuth::handleError"
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial (whitelist 코드 추가 1-2 줄 + spec)