panic: assignment to entry in nil map

Go · updated 2026-11-13

Go panics when code writes to a map that is nil: declared with var m map[K]V or left as the zero value inside a struct, and never created with make. Reading a nil map is fine (it returns zero values), which is why the code works until the first write.

panic: assignment to entry in nil map

goroutine 1 [running]:
main.(*Cache).Hit(...)
	/app/main.go:5
main.main()
	/app/main.go:9 +0x38

Quick fix

Create the map before the first write. For a struct field, do it in the constructor (NewCache) and make every caller use the constructor, or create it lazily in the method that writes. A map literal (map[string]int{}) works as well as make.

  1. Open the first frame: the line writes m[k] = v or m[k]++ on a nil map.
  2. Find where that map should have been created: a struct built with &T{} or T{} leaves map fields nil.
  3. Initialize it in a constructor with make, and use the constructor everywhere, or create it lazily before the write.
  4. For maps shared between goroutines, guard them with a sync.Mutex or use sync.Map: a nil map is one bug, concurrent writes are the next (fatal error: concurrent map writes).
go
type Cache struct{ hits map[string]int }

func NewCache() *Cache {
	return &Cache{hits: make(map[string]int)}
}

// Or create it lazily where it is written:
func (c *Cache) Hit(k string) {
	if c.hits == nil {
		c.hits = make(map[string]int)
	}
	c.hits[k]++
}
Fix it with your coding agent

Paste this into Claude Code, Cursor or Codex in the project that throws it. The agent reads this guide in plain text and applies the fix that matches your stack.

prompttext
Read https://runheed.com/errors/go-assignment-to-entry-in-nil-map.md and fix this error in this project.

Why it happens

A struct literal skipped the map field

&Cache{} and Cache{} set every field to its zero value, and the zero value of a map is nil. Code that builds the struct directly instead of through its constructor gets a nil map.

var m map[K]V without make

A package-level or local var declaration creates a nil map. Only make(...) or a literal allocates it.

A nested map was never created

m[a][b] = v needs m[a] to exist first: the inner map is nil until you create it for that key.

json.Unmarshal into a struct with the field missing

When the JSON has no value for a map field, the field stays nil, and later writes panic.

Other fixes

  • Make the struct's zero value usable: create maps lazily in every method that writes them.
  • Return copies or read-only accessors instead of exposing the map field, so all writes go through code that initializes it.

Same error, other wording

  • panic: assignment to entry in nil map [recovered]
  • fatal error: concurrent map writes

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and, when you set it, the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the "assignment to entry in nil map" panics in production, open the latest one's first frame, find where that map should be created, and initialize it in the constructor or before the write.

Setup for Go, then have your agent fix and resolve it.

Related errors

More in Undefined, None and type errors

References: The Go Programming Language Specification: map types, Go blog: Go maps in action

Spotted a mistake? Email hello@greatwork.company. About Runheed.