From f01da159174703d8dc97e44e4e34f2ea8f9482e4 Mon Sep 17 00:00:00 2001 From: hongming Date: Sat, 23 May 2026 22:31:34 -0700 Subject: [PATCH] fix(templates): preserve legacy-template surface for empty runtime (#1778) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The narrow-catalog filter in a5211050 rejected templates with empty runtime, regressing the documented backward-compat path that TestTemplatesList_LegacyTopLevelModel pins: pre-runtime_config templates declare model: at the top level and never set runtime. Tests broken on origin/main and reproducible on a fresh local checkout (manifest.json absent locally so the fallback allowlist runs; on CI the manifest happens to admit empty runtime, masking the regression — that env divergence is its own followup). Fix: skip the allowlist lookup when runtime is empty. Non-empty runtimes still go through the allowlist, preserving the filter's intent of blocking known-invalid declared runtimes. Closes #1778. --- workspace-server/internal/handlers/templates.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/workspace-server/internal/handlers/templates.go b/workspace-server/internal/handlers/templates.go index 0cf0e2255..ab1782ab1 100644 --- a/workspace-server/internal/handlers/templates.go +++ b/workspace-server/internal/handlers/templates.go @@ -204,9 +204,18 @@ func (h *TemplatesHandler) List(c *gin.Context) { return } runtime := strings.TrimSuffix(strings.TrimSpace(raw.Runtime), "-default") - if _, ok := knownRuntimes[runtime]; !ok { - log.Printf("templates list: skip %s: unsupported runtime %q", id, raw.Runtime) - return + // Empty runtime is the legacy / pre-runtime_config shape: those + // templates declare `model:` at the top level and never set + // runtime. TestTemplatesList_LegacyTopLevelModel pins the + // backward-compat contract that they keep surfacing. The + // narrow-catalog filter (a5211050) applies only when a runtime + // is declared — declared runtimes must be in the allowlist; + // absent ones fall through unchanged. + if runtime != "" { + if _, ok := knownRuntimes[runtime]; !ok { + log.Printf("templates list: skip %s: unsupported runtime %q", id, raw.Runtime) + return + } } // Model comes from either top-level (legacy) or runtime_config.model (current). -- 2.52.0