gohugoio/hugo · error

RenderString: unknown shortcode token %q

Error message

RenderString: unknown shortcode token %q

What it means

The RenderString-path analog of the placeholder-lookup failure: when RenderString renders text containing shortcodes, each shortcode is replaced by a placeholder token and later expanded; if a token in the rendered output has no matching renderer in the placeholder map (and isn't the TOC placeholder), this error is returned. The code marks it "should not happen" — an internal bookkeeping invariant broke, though unlike the page-content path it returns an error instead of panicking.

Source

Thrown at hugolib/page__content.go:1005

				if token == tocShortcodePlaceholder {
					toc, err := c.contentToC(ctx)
					if err != nil {
						return nil, err
					}
					// The Page's TableOfContents was accessed in a shortcode.
					return []byte(toc.tableOfContentsHTML), nil
				}
				renderer, found := placeholders[token]
				if found {
					repl, more, err := renderer.renderShortcode(ctx)
					if err != nil {
						return nil, err
					}
					hasShortcodeVariants = hasShortcodeVariants || more
					return repl, nil
				}
				// This should not happen.
				return nil, fmt.Errorf("RenderString: unknown shortcode token %q", token)
			}

			rendered, err = expandShortcodeTokens(ctx, rendered, tokenHandler)
			if err != nil {
				return "", err
			}
			if hasShortcodeVariants {
				pco.po.p.incrPageOutputTemplateVariation()
			}
		}

		// We need a consolidated view in $page.HasShortcode
		combined := pco.po.p.m.content.hasShortcode.Load().Or(parseInfo.shortcodeParseInfo.hasName)
		pco.po.p.m.content.hasShortcode.Store(&combined)

	} else {
		si := sourceInfo{
			filename: pco.po.p.pathOrTitle() + " (rendered from string)",

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Check the string you pass to RenderString for a literal internal placeholder pattern (HAHAHUGOSHORTCODE...) — strip or avoid feeding pipeline output back in; render from the raw source instead.
  2. Restart `hugo server` / clear caches to eliminate stale placeholder state.
  3. Reduce to a minimal reproduction; if it reproduces on a clean build with plain input, file a bug at github.com/gohugoio/hugo including the input string and shortcodes involved.
Defensive patterns

Strategy: validation

Validate before calling

{{/* ensure any shortcode named inside the RenderString input exists in layouts/_shortcodes/ */}}
{{ $out := .RenderString "{{</* myshortcode */>}}" }}

Try / catch

if err := h.Build(cfg); err != nil && strings.Contains(err.Error(), "RenderString: unknown shortcode token") {
    // shortcode used in RenderString input isn't resolvable in that context
    return err
}

Prevention

When it happens

Trigger: Calling `.RenderString` on a string containing `{{< shortcode >}}` markup where the token map built during parsing doesn't cover a token found post-render — e.g. input text that literally contains a Hugo placeholder marker, or the rendered markdown mangling/duplicating a token so it no longer matches.

Common situations: Passing content that already went through Hugo's pipeline (containing leftover placeholder strings) into RenderString; markdown processing that splits a placeholder across elements in unusual markup configurations; genuine Hugo regressions after upgrades.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/d6b90d78be93b8a5.json. Report an issue: GitHub ↗.