{"record":{"id":"b3042d78e30d8b24","repo":"golang/go","slug":"invalid-pattern-syntax","errorCode":null,"errorMessage":"invalid pattern syntax","messagePattern":"invalid pattern syntax","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/load/pkg.go","lineNumber":2176,"sourceCode":"\t\t\terr = &EmbedError{\n\t\t\t\tPattern: pattern,\n\t\t\t\tErr:     err,\n\t\t\t}\n\t\t}\n\t}()\n\n\t// TODO(rsc): All these messages need position information for better error reports.\n\tpmap = make(map[string][]string)\n\thave := make(map[string]int)\n\tdirOK := make(map[string]bool)\n\tpid := 0 // pattern ID, to allow reuse of have map\n\tfor _, pattern = range patterns {\n\t\tpid++\n\n\t\tglob, all := strings.CutPrefix(pattern, \"all:\")\n\t\t// Check pattern is valid for //go:embed.\n\t\tif _, err := pathpkg.Match(glob, \"\"); err != nil || !validEmbedPattern(glob) {\n\t\t\treturn nil, nil, fmt.Errorf(\"invalid pattern syntax\")\n\t\t}\n\n\t\t// Glob to find matches.\n\t\tmatch, err := fsys.Glob(str.QuoteGlob(str.WithFilePathSeparator(pkgdir)) + filepath.FromSlash(glob))\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\t// Filter list of matches down to the ones that will still exist when\n\t\t// the directory is packaged up as a module. (If p.Dir is in the module cache,\n\t\t// only those files exist already, but if p.Dir is in the current module,\n\t\t// then there may be other things lying around, like symbolic links or .git directories.)\n\t\tvar list []string\n\t\tfor _, file := range match {\n\t\t\t// relative path to p.Dir which begins without prefix slash\n\t\t\trel := filepath.ToSlash(str.TrimFilePathPrefix(file, pkgdir))\n\n\t\t\twhat := \"file\"","sourceCodeStart":2158,"sourceCodeEnd":2194,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/load/pkg.go#L2158-L2194","documentation":"Thrown while parsing each `//go:embed` pattern in embedGoFiles (the loop at line 2170). A pattern (after stripping an optional `all:` prefix) must (a) be accepted by path.Match as a valid glob and (b) pass validEmbedPattern (non-empty, no leading slash, no backslash, no `..`, no Windows drive). If either fails, the build aborts with this generic message. The TODO above it notes position info is missing, so the offending pattern is not named.","triggerScenarios":"Writing `//go:embed ` (empty), `//go:embed [bad`, `//go:embed ../escape`, `//go:embed \\bs`, or `//go:embed all:` (empty after prefix). The check runs pathpkg.Match(glob,\"\") first, so syntactically bad glob classes like an unmatched `[` are caught.","commonSituations":"Hand-typing embed directives; copy-paste leaving a trailing pattern empty; editor auto-formatting stripping the path; using a leading `/` assuming it is repo-root relative; CI building on Windows where a backslash slips in.","solutions":["Inspect every //go:embed line in the package and make each pattern a non-empty relative glob (e.g. `static/*.html`, `templates`).","Remove leading slashes, backslashes, and `..` segments — embed patterns are relative to the package directory and cannot escape it.","If using `all:`, ensure a real pattern follows the prefix (e.g. `all:assets`).","Validate the pattern locally with `go vet ./...` after fixing; vet reports the file:line of the directive."],"exampleFix":"// before\n//go:embed /\n// after\n//go:embed static","handlingStrategy":"validation","validationCode":"// Validate an embed pattern before relying on `go build` to catch it.\npackage embedcheck\n\nimport (\n\t\"errors\"\n\t\"path\"\n\t\"strings\"\n)\n\n// validEmbedPattern mirrors cmd/go's rules: non-empty, no leading '/',\n// no backslash, no '..'. Returns nil if acceptable.\nfunc CheckEmbedPattern(p string) error {\n\tif p == \"\" {\n\t\treturn errors.New(\"embed pattern is empty\")\n\t}\n\tif strings.Contains(p, \"\\\\\") {\n\t\treturn errors.New(\"embed pattern must not contain a backslash\")\n\t}\n\tif strings.HasPrefix(p, \"/\") {\n\t\treturn errors.New(\"embed pattern must not be absolute\")\n\t}\n\tfor _, seg := range strings.Split(p, \"/\") {\n\t\tif seg == \"..\" || seg == \"\" {\n\t\t\treturn errors.New(\"embed pattern has empty or '..' segment\")\n\t\t}\n\t}\n\tif _, err := path.Match(p, \"\"); err != nil {\n\t\treturn errors.New(\"embed pattern is not a valid glob: \" + err.Error())\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `go vet ./...` after editing any //go:embed directive — vet reports the file:line, unlike the build error.","Add a unit test that asserts every embed pattern you intend to use resolves to at least one file under the package dir."],"tags":["embed","go-embed","patterns","build"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}