ES /docs

BasePreprocessorRunner::downloadFile | error_download path: /tmp/workspace/9878/input_data/bim_mode

RCA: BasePreprocessorRunner::downloadFile | error_download (403 Forbidden)

Overview#

What Happened#

2026-04-28T16:03:28Z에 cupixworks-deviation-preprocessor-agent 서비스에서 deviation job(id: 1040523, deviation: 9878) 처리 중 BIM mesh 파일 다운로드가 HTTP 403으로 실패했다. API 서버(cupixworks-api)가 bim 19181의 mesh resource를 찾지 못해 Cupix::Errors::NotFound (ARG10002)를 반환했으며, 이로 인해 전체 preprocessor job이 실패했다.

Quick Facts#

Field Value
exception.class HTTPError
exception.message Response code 403 (Forbidden)
top_frame got/dist/source/core/index.js:913
env production, us-west-2

Affected Teams#

Team / Domain Error Count Impact
sebastiancg 1 Deviation report job 1040523 실패, bim 19181의 mesh 다운로드 불가

Timeline#

  1. 2026-04-28T16:03:28.766ZBasePreprocessorRunner::downloadFile 에서 HTTP 403 수신
  2. 2026-04-28T16:03:28.767ZPreprocessorService::run catch 블록에서 에러 로깅, job 상태를 error로 업데이트
  3. 2026-04-28T16:03:29.573Z — API 서버에서 GET /api/v1/bims/19181 요청 성공 (200)
  4. 2026-04-28T16:03:29.574Z — API 서버에서 GET /api/v1/bims/19181/resources/mesh/download 요청 실패 (403, ARG10002: "Resource not found")

Error Log#

Datadog Logs

text
BasePreprocessorRunner::downloadFile | error_download	 path: /tmp/workspace/9878/input_data/bim_model/19181/mesh.zip, url: http://api-tesla.cupix.internal/api/v1/bims/19181/resources/mesh/download, error: {
  name: 'HTTPError',
  message: 'Response code 403 (Forbidden)',
  stack: 'HTTPError: Response code 403 (Forbidden)
    at Request._onResponseBase (/tmp/agent/dist/node_modules/got/dist/source/core/index.js:913:31)
    at Request._onResponse (/tmp/agent/dist/node_modules/got/dist/source/core/index.js:948:24)
    ...'
}

Impact#

  • Service: cupixworks-deviation-preprocessor-agent
  • Team: sebastiancg
  • 발생 횟수: 1
  • 최초 발생: 2026-04-28T16:03:28.766Z
  • 최근 발생: 2026-04-28T16:03:28.766Z

Root Cause Summary#

Bim 19181에 대해 mesh resource 레코드가 resources 테이블에 존재하지 않는 상태에서 deviation preprocessor agent가 mesh 다운로드를 시도했다. API 서버의 set_multiple_resource before_action이 kind: "mesh" 또는 key: "mesh"로 resource를 조회했으나 결과가 nil이어서 Cupix::Errors::NotFound(ARG10002)를 발생시켰고, 이것이 HTTP 403으로 매핑되어 agent에 반환되었다. Agent 측에서는 이 403 에러를 처리하지 않고 그대로 throw하여 전체 job이 실패했다.

Technical Analysis#

Code Path#

  • Entry point: cupix-deviation-preprocessor-agent/src/preprocessor-service.ts:76에서 deviationRunner.downloadFiles(cpDeviation) 호출
  • DeviationReportRunner::downloadFiles에서 cpBim의 downloadFileUrl을 사용하여 다운로드 목록 구성:
applications/agents/packages/cupix-deviation-preprocessor-agent/src/runner/deviation-report-runner.ts:31-33typescript
for (const cpBim of cpBims) {
    downloadItems.push({ url: cpBim.downloadFileUrl, path: cpBim.filePath });
}
  • CPBim 모델에서 URL 생성:
applications/agents/packages/models/src/cpbim.ts:61typescript
this._meshArchiveFileDownloadUrl = CPX_API_ENDPOINT + '/bims/' + idStr + '/resources/mesh/download';
  • BasePreprocessorRunner::downloadFile에서 got.stream.get으로 HTTP 요청 수행:
applications/agents/packages/siteinsights/src/runner/base-preprocessor-runner.ts:114-119typescript
const downloadStream = got.stream.get(downloadItem.url, {
    isStream: true,
    headers: {
        'X-CUPIX-AUTH': accessToken
    }
} as any);
  • API 서버 측에서 set_multiple_resource before_action이 resource를 조회:
app/controllers/concerns/multiple_resourcable_controller.rb:145-151ruby
def set_multiple_resource
  kind_or_key = ApplicationRecord.sanitize_sql(params[:kind_or_key])

  @resource = @model.resources.where(kind: kind_or_key).or(@model.resources.where(key: kind_or_key)).first

  raise Cupix::Errors::NotFound.new(code: 'ARG10002', reason: 'Resource not found') and return if @resource.nil?
end
  • Failure point: multiple_resourcable_controller.rb:150@resource가 nil이므로 Cupix::Errors::NotFound 발생

기대 동작: Bim 19181의 mesh_stateextracted이므로 mesh resource 레코드가 존재해야 하며, 다운로드가 성공해야 한다.

실제 동작: Bim 19181은 존재하지만(GET /api/v1/bims/19181 → 200) mesh resource 레코드가 없어 다운로드 시 403이 반환되었다. Agent의 createCPBimsByBimId에서 deviation에 연결된 단일 bim을 로드하는 방식이므로 mesh_state 필터링이 적용되지 않는다(해당 필터는 createCPBims에서 facility 전체 bim 조회 시에만 사용됨).

Log Evidence#

Agent 측 에러 로그 (Datadog):

text
service:cupixworks-deviation-preprocessor-agent status:error

2026-04-28T16:03:28.766Z - BasePreprocessorRunner::downloadFile | error_download
  path: /tmp/workspace/9878/input_data/bim_model/19181/mesh.zip
  url: http://api-tesla.cupix.internal/api/v1/bims/19181/resources/mesh/download
  error: HTTPError: Response code 403 (Forbidden)

2026-04-28T16:03:28.767Z - PreprocessorService::run | end
  error: HTTPError: Response code 403 (Forbidden)

API 측 로그 (Datadog):

text
service:cupixworks-api @http.status_code:403 bims

2026-04-28T16:03:29.573Z - [200] GET /api/v1/bims/19181 (Api::V1::BimsController#show)
  user: msullivan@sebastiancg.com (id: 45497)
  session: d871516f2f950c57a54e5ee826b17d86d5071d27

2026-04-28T16:03:29.574Z - [403] GET /api/v1/bims/19181/resources/mesh/download (Api::V1::BimsController#download_multiple_resource)
  error: Cupix::Errors::NotFound, code: ARG10002, reason: "Resource not found"
  user: msullivan@sebastiancg.com (id: 45497)
  duration: 18.83ms, db: 6.4ms

사용한 Datadog 쿼리:

text
service:cupixworks-deviation-preprocessor-agent status:error @environment:production "BasePreprocessorRunner::downloadFile"
text
service:cupixworks-api status:error @http.status_code:403 "bims/19181"

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 Bim 19181의 mesh resource 레코드가 DB에 존재하지 않음 API 로그에서 ARG10002 "Resource not found" 반환, set_multiple_resource에서 @resource.nil? 조건 충족 Confirmed
H2 인증 토큰이 만료되어 403 발생 HTTP 403 status code API 로그에서 user가 정상 인식됨(id: 45497), 동일 세션으로 bim show 요청은 200 성공. 403은 NotFound 에러의 HTTP 매핑 결과임 Rejected
H3 권한 부족으로 리소스 접근 거부 HTTP 403은 보통 권한 문제를 의미 API 에러 코드가 ARG10002(Not Found)이며 권한 관련 코드(AUTH 계열)가 아님. 같은 세션/유저로 bim show는 성공 Rejected
H4 Bim 19181의 mesh_stateextracted가 아닌 상태에서 mesh가 미생성 deviation의 bim 조회 시 mesh_state 필터 미적용 (createCPBimsByBimId는 id로 직접 조회) Bim이 존재하고 deviation에 연결되어 있으므로 어느 시점에는 정상이었을 수 있음 — uncertain Inconclusive

Fix Recommendation#

즉시 조치 (Critical)#

  • deviation-report-runner.ts:68createCPBimsByBimId에서 bim 조회 후 mesh_state === 'extracted' 검증 추가
  • 또는 downloadFiles 단계에서 개별 파일 다운로드 실패 시 해당 bim을 건너뛰고 나머지를 계속 처리하도록 에러 핸들링 개선 (base-preprocessor-runner.ts:92-127)

단기 개선 (1주 이내)#

  • BasePreprocessorRunner::downloadFile에서 HTTP 403/404 응답 시 재시도하지 않고 명확한 에러 메시지와 함께 실패 처리하도록 개선. 현재는 got의 기본 retry 로직에 의존하고 있음
  • API 서버의 set_multiple_resource에서 resource not found를 403이 아닌 404로 매핑하도록 변경 검토 (Cupix::Errors::NotFound가 403으로 매핑되는 것은 의미적으로 혼란을 줌)

장기 개선 (재발 방지)#

  • Deviation job 생성 시점에 연결된 bim의 mesh resource 존재 여부를 사전 검증하는 validation step 추가
  • Bim mesh extraction 완료 후 resource 레코드 생성이 atomic하게 이루어지도록 보장하는 프로세스 검증

Monitoring#

  • service:cupixworks-deviation-preprocessor-agent status:error "error_download" 모니터 설정으로 다운로드 실패 추적
  • Deviation job 실패율 메트릭 추가:
text
service:cupixworks-deviation-preprocessor-agent "updateErrorActionJob"

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: standard