Description
Two independent defects in the training form's Base Model dropdown (ui/src/Components/BaseModelDropdown.jsx).
1. The selected base model is never displayed. baseModelId is read in three places in BaseModelDropdown.jsx (the componentState destructure, the options.find that computes selectedOption, and the selectedOptions prop) but it is never written anywhere in the UI. handleOptionSelect only sets initialWeightsUrl.
The submitted payload is correct, because initialWeightsUrl is what training consumes, so this is a display-only defect. But the dropdown clears itself the moment you pick something, which reads as "the selection didn't take", and reopening an existing model never re-selects its catalog entry.
2. The catalog is empty when training is launched from the labeling tool. CreateEditModelTrainingModal declares eventTypes: proptypes.array.isRequired, but only two of its four render sites pass it:
| Render site |
Passes eventTypes? |
ProjectManagement/LayerCard.jsx |
yes |
ProjectManagement/LayerRow.jsx |
yes |
LabelingTool/RightPanel.jsx |
no |
LabelingTool/LabelingToolRightPanel.jsx |
no |
fetchModelCatalog built its query by string concatenation, so "eventTypes=" + undefined produced the literal query eventTypes=undefined. The API treats that as a real event type, matches nothing, and returns an empty catalog.
Net effect: the dropdown populates when training is started from the project page, and is always empty when started from the labeling tool.
Additional notes
Two smaller problems in the same component, worth folding into any fix:
m.value.description.substring(0, 30) throws when description is null, which is common for externally catalogued checkpoints.
- The option key falls back to
"none" for every entry without a modelId, so all external catalog entries collapse onto a single React key. baseModelName is a safe fallback since the API already rejects duplicates with a 409.
Suggested fix, which I have working locally:
- Write
baseModelId and initialWeightsUrl together in one functional state update. They must be a single update because onFormChange spreads a captured componentState, so two sequential calls drop the first write.
- Resolve
baseModelId from an existing initialWeightsUrl after the catalog loads, so editing an existing model preselects correctly.
- Replace the concatenated query with
URLSearchParams, omitting absent filters entirely rather than stringifying them, and unit test it.
- Separately, fix the two labeling-tool components so they pass the
eventTypes prop they are declared to require. The query builder change makes the symptom go away, but the prop is still missing and will affect anything else that reads it.
One note for anyone reproducing this locally: GetModelCatalog, PutModelCatalog and DeleteModelCatalog are currently the only routes in function_app.py hardcoded to AuthLevel.FUNCTION rather than the AUTH_LEVEL constant, so they ignore DEVELOPMENT_MODE and return 401 against the compose stack. The dropdown cannot be exercised locally until that is changed.
Steps to Reproduce
- Catalog at least one model so
GetModelCatalog has something to return.
- Open a project, expand an image layer, choose Train Model, and open the Base Model dropdown. Select an entry. (Defect 1)
- Open the same training form from inside the labeling tool right-hand panel and open the Base Model dropdown. (Defect 2)
Expected Behavior
- The dropdown displays the model you selected, and reopening a model that was trained from a base model preselects that entry.
- The dropdown lists the same catalog entries regardless of whether training was launched from the project page or from the labeling tool.
Actual Behavior
- The dropdown goes blank immediately after selection, and never preselects an entry when editing an existing model.
- From the labeling tool the dropdown is always empty, because the request goes out as
GetModelCatalog?eventTypes=undefined&imagerySource=<source>.
Confirmed directly against the API with a single catalogued entry:
| Request |
Response |
GetModelCatalog?imagerySource=Planet |
returns the model |
GetModelCatalog?imagerySource=Planet&eventTypes=Hurricane |
returns the model |
GetModelCatalog?imagerySource=Planet&eventTypes=undefined |
{"modelCatalog": []} |
Environment
- Deployment type: local
docker/docker-compose.yml stack
- HASTE commit:
d1ecf64 on main
- Browser-side only; reproduced against
hastefuncapi running in the compose stack
Logs / Stack Trace
Not a crash. The failing request, from the browser network tab:
GET /api/GetModelCatalog?eventTypes=undefined&imagerySource=Planet
200 {"modelCatalog": []}
Checklist
Description
Two independent defects in the training form's Base Model dropdown (
ui/src/Components/BaseModelDropdown.jsx).1. The selected base model is never displayed.
baseModelIdis read in three places inBaseModelDropdown.jsx(thecomponentStatedestructure, theoptions.findthat computesselectedOption, and theselectedOptionsprop) but it is never written anywhere in the UI.handleOptionSelectonly setsinitialWeightsUrl.The submitted payload is correct, because
initialWeightsUrlis what training consumes, so this is a display-only defect. But the dropdown clears itself the moment you pick something, which reads as "the selection didn't take", and reopening an existing model never re-selects its catalog entry.2. The catalog is empty when training is launched from the labeling tool.
CreateEditModelTrainingModaldeclareseventTypes: proptypes.array.isRequired, but only two of its four render sites pass it:eventTypes?ProjectManagement/LayerCard.jsxProjectManagement/LayerRow.jsxLabelingTool/RightPanel.jsxLabelingTool/LabelingToolRightPanel.jsxfetchModelCatalogbuilt its query by string concatenation, so"eventTypes=" + undefinedproduced the literal queryeventTypes=undefined. The API treats that as a real event type, matches nothing, and returns an empty catalog.Net effect: the dropdown populates when training is started from the project page, and is always empty when started from the labeling tool.
Additional notes
Two smaller problems in the same component, worth folding into any fix:
m.value.description.substring(0, 30)throws whendescriptionis null, which is common for externally catalogued checkpoints."none"for every entry without amodelId, so all external catalog entries collapse onto a single React key.baseModelNameis a safe fallback since the API already rejects duplicates with a 409.Suggested fix, which I have working locally:
baseModelIdandinitialWeightsUrltogether in one functional state update. They must be a single update becauseonFormChangespreads a capturedcomponentState, so two sequential calls drop the first write.baseModelIdfrom an existinginitialWeightsUrlafter the catalog loads, so editing an existing model preselects correctly.URLSearchParams, omitting absent filters entirely rather than stringifying them, and unit test it.eventTypesprop they are declared to require. The query builder change makes the symptom go away, but the prop is still missing and will affect anything else that reads it.One note for anyone reproducing this locally:
GetModelCatalog,PutModelCatalogandDeleteModelCatalogare currently the only routes infunction_app.pyhardcoded toAuthLevel.FUNCTIONrather than theAUTH_LEVELconstant, so they ignoreDEVELOPMENT_MODEand return 401 against the compose stack. The dropdown cannot be exercised locally until that is changed.Steps to Reproduce
GetModelCataloghas something to return.Expected Behavior
Actual Behavior
GetModelCatalog?eventTypes=undefined&imagerySource=<source>.Confirmed directly against the API with a single catalogued entry:
GetModelCatalog?imagerySource=PlanetGetModelCatalog?imagerySource=Planet&eventTypes=HurricaneGetModelCatalog?imagerySource=Planet&eventTypes=undefined{"modelCatalog": []}Environment
docker/docker-compose.ymlstackd1ecf64onmainhastefuncapirunning in the compose stackLogs / Stack Trace
Checklist