All server-rendered HTML pages (index, login, sources list, source detail, edit, logs, profile) return HTTP 200 with an empty body (1 byte: newline). The web UI is completely non-functional.
Root Cause
In internal/handlers/handlers.go, parsePageTemplate() uses:
Go's template.ParseFS names the resulting template set after the first file parsed (htmlheader.html). When tmpl.Execute(w, data) is called in renderTemplate(), it executes the root template — which is htmlheader.html. Since that file consists entirely of a {{define "htmlheader"}}...{{end}} block, the root template is empty.
The page-specific templates (e.g., source_detail.html) have:
Since page templates start with {{template "base" .}} (a top-level action), executing the root template will invoke the base template, which in turn uses the defined content and title blocks.
Impact
The entire web management UI is blank. Users cannot see or interact with any page. Only the JSON healthcheck endpoint works. This blocks the 1.0 release.
## Bug
All server-rendered HTML pages (index, login, sources list, source detail, edit, logs, profile) return HTTP 200 with an empty body (1 byte: newline). The web UI is completely non-functional.
## Root Cause
In `internal/handlers/handlers.go`, `parsePageTemplate()` uses:
```go
func parsePageTemplate(pageFile string) *template.Template {
return template.Must(
template.ParseFS(templates.Templates, "htmlheader.html", "navbar.html", "base.html", pageFile),
)
}
```
Go's `template.ParseFS` names the resulting template set after the first file parsed (`htmlheader.html`). When `tmpl.Execute(w, data)` is called in `renderTemplate()`, it executes the root template — which is `htmlheader.html`. Since that file consists entirely of a `{{define "htmlheader"}}...{{end}}` block, the root template is empty.
The page-specific templates (e.g., `source_detail.html`) have:
```
{{template "base" .}}
{{define "title"}}...{{end}}
{{define "content"}}...{{end}}
```
The `{{template "base" .}}` invocation never executes because `Execute()` runs the (empty) root template, not the page template.
## Evidence
Testing with curl:
```
$ curl -s http://localhost:9999/ | wc -c
0
$ curl -s http://localhost:9999/pages/login | wc -c
0
```
The healthcheck (`/.well-known/healthcheck`) still works because it uses `respondJSON()` directly, not template rendering.
## Fix
Two options:
**Option A** (simpler): Change `renderTemplate()` to use `ExecuteTemplate` with the page template name:
```go
if err := tmpl.ExecuteTemplate(w, pageFile, m); err != nil {
```
But this requires page templates to use the file's own name rather than `{{template "base" .}}`.
**Option B** (recommended): Restructure so the base template is the root. Parse the page file first so it becomes the root template:
```go
func parsePageTemplate(pageFile string) *template.Template {
return template.Must(
template.ParseFS(templates.Templates, pageFile, "base.html", "htmlheader.html", "navbar.html"),
)
}
```
Since page templates start with `{{template "base" .}}` (a top-level action), executing the root template will invoke the base template, which in turn uses the defined `content` and `title` blocks.
## Impact
The entire web management UI is blank. Users cannot see or interact with any page. Only the JSON healthcheck endpoint works. This blocks the 1.0 release.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Bug
All server-rendered HTML pages (index, login, sources list, source detail, edit, logs, profile) return HTTP 200 with an empty body (1 byte: newline). The web UI is completely non-functional.
Root Cause
In
internal/handlers/handlers.go,parsePageTemplate()uses:Go's
template.ParseFSnames the resulting template set after the first file parsed (htmlheader.html). Whentmpl.Execute(w, data)is called inrenderTemplate(), it executes the root template — which ishtmlheader.html. Since that file consists entirely of a{{define "htmlheader"}}...{{end}}block, the root template is empty.The page-specific templates (e.g.,
source_detail.html) have:The
{{template "base" .}}invocation never executes becauseExecute()runs the (empty) root template, not the page template.Evidence
Testing with curl:
The healthcheck (
/.well-known/healthcheck) still works because it usesrespondJSON()directly, not template rendering.Fix
Two options:
Option A (simpler): Change
renderTemplate()to useExecuteTemplatewith the page template name:But this requires page templates to use the file's own name rather than
{{template "base" .}}.Option B (recommended): Restructure so the base template is the root. Parse the page file first so it becomes the root template:
Since page templates start with
{{template "base" .}}(a top-level action), executing the root template will invoke the base template, which in turn uses the definedcontentandtitleblocks.Impact
The entire web management UI is blank. Users cannot see or interact with any page. Only the JSON healthcheck endpoint works. This blocks the 1.0 release.