gohugoio/hugo · error

missing taxonomy

Error message

missing taxonomy: %s

What it means

Returned during pageMap.CreateSiteTaxonomies when, inside the per-view walker, taxonomies[viewName.plural] is nil for a KindTerm page being processed. The map was initialized for that plural key just above (line 1174), so a nil entry implies the viewName.plural being iterated does not match a populated key — an internal taxonomy configuration inconsistency, not a user content error per se.

Solutions

  1. Review the taxonomies config block: each entry should be singular: plural form (e.g. tag: tags), non-empty, distinct.
  2. Ensure no plural key is empty or duplicated across taxonomies.
  3. If using multilingual taxonomies, verify the per-language config is consistent.
  4. Report with the failing plural name if config looks correct — this often signals an internal bug.

Example fix

# before (config.toml)
[taxonomies]
  tag = ""   # empty plural triggers missing-taxonomy
# after
[taxonomies]
  tag = "tags"
Defensive patterns

Strategy: validation

Validate before calling

func validateTaxonomyConfig(tax map[string]string) error {
    seen := map[string]bool{}
    for sing, plur := range tax {
        if plur == "" || sing == "" { return fmt.Errorf("empty taxonomy key") }
        if seen[plur] { return fmt.Errorf("duplicate plural %q", plur) }
        seen[plur] = true
    }
    return nil
}

Prevention

When it happens

Trigger: taxonomyConfig.views contains a view whose plural key, when used to look up in the freshly-built taxonomies map, returns nil. This can happen with malformed taxonomy config (e.g. plural/singular misconfiguration, duplicate/empty plural keys) or a programming regression in how views are configured.

Common situations: Misconfiguring taxonomies in hugo config (e.g. tag/tags collision, empty plural, singular==plural edge cases); upgrading Hugo across a version where taxonomy key handling changed; custom taxonomies with reserved names.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/26209c0fef92f60c. Report an issue: GitHub.

Appendix: source

Thrown at hugolib/content_map_page.go:1189

	for _, viewName := range m.cfg.taxonomyConfig.views {
		key := viewName.pluralTreeKey
		taxonomies[viewName.plural] = make(page.Taxonomy)
		w := &doctree.NodeShiftTreeWalker[contentNode]{
			Tree:     m.treePages,
			Prefix:   paths.AddTrailingSlash(key),
			LockType: doctree.LockTypeRead,
			Handle: func(s string, n contentNode) (radix.WalkFlag, error) {
				p := n.(*pageState)

				switch p.Kind() {
				case kinds.KindTerm:
					if !p.m.shouldList(true) {
						return radix.WalkContinue, nil
					}
					taxonomy := taxonomies[viewName.plural]
					if taxonomy == nil {
						return radix.WalkStop, fmt.Errorf("missing taxonomy: %s", viewName.plural)
					}
					if p.m.term == "" {
						panic("term is empty")
					}
					k := strings.ToLower(p.m.term)

					err := m.treeTaxonomyEntries.WalkPrefix(
						doctree.LockTypeRead,
						paths.AddTrailingSlash(s),
						func(ss string, wn *weightedContentNode) (bool, error) {
							taxonomy[k] = append(taxonomy[k], page.NewWeightedPage(wn.weight, wn.n.(page.Page), wn.term.Page()))
							return false, nil
						},
					)
					if err != nil {
						return radix.WalkStop, err
					}

View on GitHub (pinned to 52c9bd7908)