gohugoio/hugo · error

%q is not a valid placeholder (valid values are :cacheDir or

Error message

%q is not a valid placeholder (valid values are :cacheDir or :resourceDir)

What it means

Returned by resolveDirPlaceholder when a path segment in a cache dir starts with ':' but is not one of the recognized placeholders :resourceDir, :cacheDir, or :project (compared case-insensitively). Any colon-prefixed segment is treated as a placeholder, so unknown tokens are rejected rather than silently written as literal directory names. Note the message lists only :cacheDir and :resourceDir even though :project is also accepted.

Source

Thrown at cache/filecache/filecache_config.go:316

		c[k] = v
	}

	return c, nil
}

// Resolves :resourceDir => /myproject/resources etc., :cacheDir => ...
func resolveDirPlaceholder(fs afero.Fs, bcfg config.BaseConfig, placeholder string) (cacheDir string, isResource bool, err error) {
	switch strings.ToLower(placeholder) {
	case ":resourcedir":
		return "", true, nil
	case ":cachedir":
		return bcfg.CacheDir, false, nil
	case ":project":
		return filepath.Base(bcfg.WorkingDir), false, nil
	}

	return "", false, fmt.Errorf("%q is not a valid placeholder (valid values are :cacheDir or :resourceDir)", placeholder)
}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Correct the placeholder to :cacheDir, :resourceDir, or :project (case-insensitive).
  2. If you meant a literal directory, remove the leading colon or use an absolute path.
  3. For temp-dir caching, set the top-level cacheDir to the desired location and use :cacheDir in the caches entries.

Example fix

# before
[caches.getresource]
dir = ":cachedirr/getresource"
# after
[caches.getresource]
dir = ":cacheDir/getresource"
Defensive patterns

Strategy: validation

Validate before calling

if strings.HasPrefix(dir, ":") {
    first := strings.SplitN(dir, string(filepath.Separator), 2)[0]
    if first != ":cacheDir" && first != ":resourceDir" {
        return fmt.Errorf("invalid placeholder %q; use :cacheDir or :resourceDir", first)
    }
}

Prevention

When it happens

Trigger: caches.<name>.dir containing a segment like `:cachedirr`, `:tmpDir`, `:home`, or any misspelled/unsupported colon token; the check runs per '/'-separated segment during DecodeConfig.

Common situations: Typos in placeholder names, copying placeholder syntax from other tools (e.g. `:tmp`), or expecting env-var-style tokens to work; Windows users sometimes hit adjacent path/colon confusion when hand-writing dirs.

Related errors


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