{"record":{"id":"7ffd6529bd38364e","repo":"caddyserver/caddy","slug":"w-at-s-d-import-chain-s","errorCode":null,"errorMessage":"%w, at %s:%d import chain ['%s']","messagePattern":"%w, at (.+?):(.+?) import chain \\['(.+?)'\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/caddyfile/dispenser.go","lineNumber":445,"sourceCode":"// the end of the input when searching for the next token.\nfunc (d *Dispenser) EOFErr() error {\n\treturn d.Errf(\"unexpected EOF\")\n}\n\n// Err generates a custom parse-time error with a message of msg.\nfunc (d *Dispenser) Err(msg string) error {\n\treturn d.WrapErr(errors.New(msg))\n}\n\n// Errf is like Err, but for formatted error messages\nfunc (d *Dispenser) Errf(format string, args ...any) error {\n\treturn d.WrapErr(fmt.Errorf(format, args...))\n}\n\n// WrapErr takes an existing error and adds the Caddyfile file and line number.\nfunc (d *Dispenser) WrapErr(err error) error {\n\tif len(d.Token().imports) > 0 {\n\t\treturn fmt.Errorf(\"%w, at %s:%d import chain ['%s']\", err, d.File(), d.Line(), strings.Join(d.Token().imports, \"','\"))\n\t}\n\treturn fmt.Errorf(\"%w, at %s:%d\", err, d.File(), d.Line())\n}\n\n// Delete deletes the current token and returns the updated slice\n// of tokens. The cursor is not advanced to the next token.\n// Because deletion modifies the underlying slice, this method\n// should only be called if you have access to the original slice\n// of tokens and/or are using the slice of tokens outside this\n// Dispenser instance. If you do not re-assign the slice with the\n// return value of this method, inconsistencies in the token\n// array will become apparent (or worse, hide from you like they\n// did me for 3 and a half freaking hours late one night).\nfunc (d *Dispenser) Delete() []Token {\n\tif d.cursor >= 0 && d.cursor <= len(d.tokens)-1 {\n\t\td.tokens = append(d.tokens[:d.cursor], d.tokens[d.cursor+1:]...)\n\t\td.cursor--\n\t}","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/caddyfile/dispenser.go#L427-L463","documentation":"WrapErr decorates any Caddyfile parse error with the file and line of the current token; this variant fires when the token came from an imported file (via import), appending the full import chain so you can trace which snippet imported the failing line.","triggerScenarios":"Any Caddyfile error constructed with d.Err/d.Errf/d.WrapErr where the current token has a non-empty imports list — i.e. the error is inside a file or snippet reached through one or more import statements.","commonSituations":"A syntax error or unrecognized directive inside an imported snippet (e.g. site snippets in a separate file pulled in with import blocks/*.caddy). The import chain names each hop, so files deep in an import tree are debuggable.","solutions":["Open the file:line in the message; the import chain after 'import chain' lists the hops from the main Caddyfile","Fix the underlying error described before the ', at file:line' part","If the chain is confusing, temporarily inline the imported file to get a flat error","Check for stale imported files that reference directives removed in your Caddy version"],"exampleFix":"# before: snippets/site.caddy has a typo\nroot * /vr-srv  # inside import snippets/*.caddy\n# after\nroot * /var/www","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := serverType.Setup(serverBlocks); err != nil {\n    var line, file string\n    if _, e := fmt.Sscanf(err.Error(), \"%s at %s\", &line, &file); e == nil {\n        // surface file/line and import chain to the user in CI output\n    }\n}","preventionTips":["Run `caddy adapt` in CI to catch snippet errors before deploy","Keep import trees shallow; prefer one level of snippets","Version-control imported snippet files alongside the main Caddyfile"],"tags":["caddyfile","parse-error","imports","diagnostics"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}