Problem
A ZIP component and the Tapis engine are not compatible. This is known and it is not new.
The defect is that nothing handles it. The user gets a 500 with a JSON parser message.
Measured live at TACC on 2026-08-09, signed in as mosorio@portals:
POST https://ensemble-manager.mint.tacc.utexas.edu/v1/executionEngines/tapis -> 500
{"error":"Unexpected token 'P', \"PK...\" is not valid JSON"}
PK followed by bytes 03 04 is the ZIP magic number.
Cause
When the engine is Tapis, ExecutionCreation.ts:225 calls loadComponentFromTapis(model.code_url).
That method fetches has_component_location and runs await response.json(), then reads
result. It expects the Tapis Apps API envelope — a Tapis app definition.
The model was HAND Setup for Hays catchment. Its component location is a MINT localex bundle:
https://github.com/mintproject/HAND-TauDEM/raw/v2.1.4/hand_v2_mint_component.zip
So response.json() parses a ZIP and throws. The error escapes as a plain 500.
The input dataset is not involved. The submit was repeated with a GeoTIFF input instead of a
ZIP input. The response was identical, byte for byte — same etag, same content-length.
Scale at TACC
315 model configurations:
has_component_location |
Count |
.zip (localex bundle) |
171 |
| empty |
105 |
.cwl |
19 |
| Tapis app URL |
17 |
So 171 configurations will 500 on a Tapis deployment, and TACC runs Tapis
(execution_engine.type: tapis in the Helm values; the Lit config sets
REACT_APP_EXECUTION_ENGINE = "tapis").
Only 5 of the 17 Tapis app URLs are on the portals tenant with data annotated in CKAN.
The single successful tapis execution at TACC is from 2025-05-16, older than this code
path. Every execution since is localex.
Asks
- Fail with a clear message. Detect that the component is not a Tapis app before parsing.
Return the reason, not a parser error. This alone turns an unexplainable 500 into an
answerable one.
- Say which engines a configuration supports. The catalog does not record it. Today the
only way to know is to read the file extension of has_component_location.
- Decide whether a ZIP component should be registered as a Tapis app, or whether Tapis
deployments should hide the configurations they cannot run.
Context
Found while resolving #92. It does not
block #92, which picks a Tapis-ready configuration instead. It is pre-existing and the Lit UI
behaves the same, so it is not a ui-react regression and it does not block the flip
(#77). Filed so it is not lost.
Problem
A ZIP component and the Tapis engine are not compatible. This is known and it is not new.
The defect is that nothing handles it. The user gets a 500 with a JSON parser message.
Measured live at TACC on 2026-08-09, signed in as
mosorio@portals:PKfollowed by bytes03 04is the ZIP magic number.Cause
When the engine is Tapis,
ExecutionCreation.ts:225callsloadComponentFromTapis(model.code_url).That method fetches
has_component_locationand runsawait response.json(), then readsresult. It expects the Tapis Apps API envelope — a Tapis app definition.The model was
HAND Setup for Hays catchment. Its component location is a MINT localex bundle:So
response.json()parses a ZIP and throws. The error escapes as a plain 500.The input dataset is not involved. The submit was repeated with a GeoTIFF input instead of a
ZIP input. The response was identical, byte for byte — same
etag, samecontent-length.Scale at TACC
315 model configurations:
has_component_location.zip(localex bundle).cwlSo 171 configurations will 500 on a Tapis deployment, and TACC runs Tapis
(
execution_engine.type: tapisin the Helm values; the Lit config setsREACT_APP_EXECUTION_ENGINE = "tapis").Only 5 of the 17 Tapis app URLs are on the
portalstenant with data annotated in CKAN.The single successful
tapisexecution at TACC is from 2025-05-16, older than this codepath. Every execution since is
localex.Asks
Return the reason, not a parser error. This alone turns an unexplainable 500 into an
answerable one.
only way to know is to read the file extension of
has_component_location.deployments should hide the configurations they cannot run.
Context
Found while resolving #92. It does not
block #92, which picks a Tapis-ready configuration instead. It is pre-existing and the Lit UI
behaves the same, so it is not a
ui-reactregression and it does not block the flip(#77). Filed so it is not lost.