The Error MessageYou refresh your Go web application, expecting a personalized dashboard, but find a 500 error instead. Checking the logs reveals this specific failure:
template: mytemplate:5:8: executing "mytemplate" at : can't evaluate field Username in type main.User
This happens because the template engine tried to access a piece of data it couldn't see. Usually, the culprit is a private field or a misunderstanding of how the "dot" context shifts during execution.
Root Cause: Exported vs. Unexported FieldsVisibility rules in Go are simple: uppercase is public (exported), lowercase is private (unexported). The html/template package uses reflection to read your structs at runtime. However, reflection cannot bypass Go's security to access private fields.
Imagine your struct looks like this:
type User struct {
username string // Private
Email string // Public
}
Even if you pass the data correctly, {{.username}} will fail. The engine treats private fields as if they don't exist.
Fixing the Error### 1. Capitalize Your Struct FieldsThe quickest fix involves changing your struct definition. Ensure every field used in a template starts with an uppercase letter.
type User struct {
Username string
Email string
}
Update your template to match: <p>Hello, {{.Username}}!</p>. This simple change resolves 90% of these errors.
2. Master the "Dot" ContextThe "dot" (.) represents your current cursor. It changes when you enter a {{range}} or {{with}} block. If you iterate through a list of blog posts, the dot is no longer your top-level data; it becomes the specific post you're currently processing.
{{range .Posts}}
<p>Posted by: {{.User.Username}}</p> <!-- This often fails! -->
{{end}}
If User is a property of your global data and not the Post struct, the template will crash. Use $ to jump back to the original data root passed to the template:
{{range .Posts}}
<li>Written by: {{$.User.Username}}</li> <!-- This works! -->
{{end}}
3. Check Case SensitivityGo is unforgiving with casing. If your struct defines Username but your HTML template calls {{.UserName}} (note the capital 'N'), the evaluation fails immediately. Go templates do not provide "fuzzy matching" for field names.
Verify the FixDon't restart your entire server just to test a small fix. Use a quick standalone script to confirm the template parses and executes correctly.
package main
import (
"html/template"
"os"
)
type User struct {
Username string
}
func main() {
const doc = `<p>Hello, {{.Username}}!</p>`
t := template.Must(template.New("test").Parse(doc))
// Test with real data
err := t.Execute(os.Stdout, User{Username: "Alice"})
if err != nil {
panic(err)
}
}

