Bug description
The workload create API accepts a runtime_config object typed directly as templates.RuntimeConfig (pkg/api/v1/workload_types.go:49), and swagger documents all four of its fields (docs/server/swagger.yaml:4376-4419). But runtimeConfigFromRequest (pkg/api/v1/workload_service.go:506-527) only copies builder_image and additional_packages. build_with and runtime_env are dropped with no error.
The early return at workload_service.go:522 compounds it: a request setting only those two fields returns nil, so no runtime config reaches the build at all.
Steps to reproduce
curl -X POST http://localhost:8080/api/v1beta/workloads \
-H 'Content-Type: application/json' \
-d '{
"name": "arxiv-test",
"image": "uvx://arxiv-mcp-server",
"runtime_config": {
"build_with": ["mcp<2"],
"runtime_env": {"MY_FLAG": "1"}
}
}'
Compare against the equivalent CLI invocation, which honors both fields:
thv run --build-with 'mcp<2' uvx://arxiv-mcp-server
Expected behavior
Either the generated Dockerfile contains uv tool install --with 'mcp<2' and an ENV MY_FLAG="1" in the runtime stage, or the request is rejected with an error naming the unsupported fields.
Actual behavior
The request succeeds and both fields are silently ignored. The Dockerfile has no --with argument and no MY_FLAG. Because this request sets no other runtime_config field, runtimeConfigFromRequest returns nil and the build falls back entirely to transport defaults.
Additional context
The same two-field assumption repeats in runtimeConfigForImageBuild (merge at workload_service.go:569-578), getBaseRuntimeConfig (workload_service.go:583-597), and the response mapper (pkg/api/v1/workload_types.go:400-401), so a runtime config carrying those fields would not round-trip either.
Both fields work through the CLI path, which constructs templates.RuntimeConfig directly and lets loadRuntimeConfig merge and validate it (pkg/runner/protocol.go:172-233). Only the API path loses them. No test in pkg/api/v1/workload_service_test.go covers either field, which suggests an oversight rather than a deliberate API restriction.
Fix is either plumbing both fields through all four functions with validateRuntimeConfig extended to match, or rejecting them explicitly and removing them from the swagger schema. Silently ignoring documented fields is the worst of the three.
Environment
- ToolHive version: v0.42.0 (
2c623d57)
Bug description
The workload create API accepts a
runtime_configobject typed directly astemplates.RuntimeConfig(pkg/api/v1/workload_types.go:49), and swagger documents all four of its fields (docs/server/swagger.yaml:4376-4419). ButruntimeConfigFromRequest(pkg/api/v1/workload_service.go:506-527) only copiesbuilder_imageandadditional_packages.build_withandruntime_envare dropped with no error.The early return at
workload_service.go:522compounds it: a request setting only those two fields returnsnil, so no runtime config reaches the build at all.Steps to reproduce
Compare against the equivalent CLI invocation, which honors both fields:
thv run --build-with 'mcp<2' uvx://arxiv-mcp-serverExpected behavior
Either the generated Dockerfile contains
uv tool install --with 'mcp<2'and anENV MY_FLAG="1"in the runtime stage, or the request is rejected with an error naming the unsupported fields.Actual behavior
The request succeeds and both fields are silently ignored. The Dockerfile has no
--withargument and noMY_FLAG. Because this request sets no otherruntime_configfield,runtimeConfigFromRequestreturnsniland the build falls back entirely to transport defaults.Additional context
The same two-field assumption repeats in
runtimeConfigForImageBuild(merge atworkload_service.go:569-578),getBaseRuntimeConfig(workload_service.go:583-597), and the response mapper (pkg/api/v1/workload_types.go:400-401), so a runtime config carrying those fields would not round-trip either.Both fields work through the CLI path, which constructs
templates.RuntimeConfigdirectly and letsloadRuntimeConfigmerge and validate it (pkg/runner/protocol.go:172-233). Only the API path loses them. No test inpkg/api/v1/workload_service_test.gocovers either field, which suggests an oversight rather than a deliberate API restriction.Fix is either plumbing both fields through all four functions with
validateRuntimeConfigextended to match, or rejecting them explicitly and removing them from the swagger schema. Silently ignoring documented fields is the worst of the three.Environment
2c623d57)