{"record":{"id":"cf9be4215d1cacd7","repo":"gohugoio/hugo","slug":"must-provide-cache-dir","errorCode":null,"errorMessage":"must provide cache Dir","messagePattern":"must provide cache Dir","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cache/filecache/filecache_config.go","lineNumber":245,"sourceCode":"\t\t}\n\n\t\tdc := &mapstructure.DecoderConfig{\n\t\t\tResult:           &cc,\n\t\t\tDecodeHook:       mapstructure.StringToTimeDurationHookFunc(),\n\t\t\tWeaklyTypedInput: true,\n\t\t}\n\n\t\tdecoder, err := mapstructure.NewDecoder(dc)\n\t\tif err != nil {\n\t\t\treturn c, err\n\t\t}\n\n\t\tif err := decoder.Decode(v); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to decode filecache config: %w\", err)\n\t\t}\n\n\t\tif cc.Dir == \"\" {\n\t\t\treturn c, errors.New(\"must provide cache Dir\")\n\t\t}\n\n\t\tc[k] = cc\n\n\t}\n\n\tfor k, v := range c {\n\t\tdir := filepath.ToSlash(filepath.Clean(v.Dir))\n\t\thadSlash := strings.HasPrefix(dir, \"/\")\n\t\tparts := strings.Split(dir, \"/\")\n\n\t\tfor i, part := range parts {\n\t\t\tif strings.HasPrefix(part, \":\") {\n\t\t\t\tresolved, isResource, err := resolveDirPlaceholder(fs, bcfg, part)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn c, err\n\t\t\t\t}\n\t\t\t\tif isResource {","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/cache/filecache/filecache_config.go#L227-L263","documentation":"When decoding the filecache configuration from Hugo config, after mapstructure decodes a cache entry, if the Dir field is empty the loader rejects it with 'must provide cache Dir'. Every named cache must declare a directory.","triggerScenarios":"A caching config block (e.g. [caches.assets]) sets fields like maxAge but omits dir, leaving Dir empty after decode and hitting filecache_config.go:244-245.","commonSituations":"User overrides a cache's maxAge but forgets dir; a typo renames dir to something else; copying a partial config example from docs.","solutions":["Add dir to the cache entry in config (e.g. dir = \":cacheDir\" or an absolute path)","Use a placeholder such as :cacheDir / :resource so Hugo resolves the path","Validate the full caches block against the Hugo documentation"],"exampleFix":"# before\n[caches.assets]\nmaxAge = \"24h\"\n# after\n[caches.assets]\ndir = \":cacheDir\"\nmaxAge = \"24h\"","handlingStrategy":"validation","validationCode":"for name, cc := range cacheConfigs {\n    if cc.Dir == \"\" {\n        return fmt.Errorf(\"cache %q missing dir\", name)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair a cache maxAge with a dir in Hugo config","Use Hugo's documented dir placeholders (:cacheDir, :resource)"],"tags":["filecache","config","go","hugo-config"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}