{"record":{"id":"6b8f83ec0ed5b81c","repo":"projectdiscovery/nuclei","slug":"expected-1-package-got-d","errorCode":null,"errorMessage":"expected 1 package, got %d","messagePattern":"expected 1 package, got (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/js/devtools/bindgen/generator.go","lineNumber":129,"sourceCode":"\t}\n\treturn modules, nil\n}\n\n// CreateTemplateData creates a TemplateData structure from a directory\n// of go source code.\nfunc CreateTemplateData(directory string, packagePrefix string) (*TemplateData, error) {\n\tfmt.Println(directory)\n\tfset := token.NewFileSet()\n\n\tpkgs, err := parsePackageDir(fset, directory)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"could not parse directory\")\n\t}\n\tif len(pkgs) == 0 {\n\t\treturn nil, errors.New(\"no packages found\")\n\t}\n\tif len(pkgs) != 1 {\n\t\treturn nil, fmt.Errorf(\"expected 1 package, got %d\", len(pkgs))\n\t}\n\n\tconfig := &types.Config{\n\t\tImporter: importer.ForCompiler(fset, \"source\", nil),\n\t}\n\tvar packageName string\n\tvar pkgMain *parsedPackage\n\tvar files []*ast.File\n\tfor name, pkg := range pkgs {\n\t\tpackageName = name\n\t\tpkgMain = pkg\n\t\tbreak\n\t}\n\tfilenames := make([]string, 0, len(pkgMain.files))\n\tfor filename := range pkgMain.files {\n\t\tfilenames = append(filenames, filename)\n\t}\n\tsort.Strings(filenames)","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/devtools/bindgen/generator.go#L111-L147","documentation":"parsePackageDir returned more than one package for the directory passed to CreateTemplateData, but bindgen processes exactly one module package at a time. Multiple package clauses (or package variants behind build tags) in the same directory trigger it.","triggerScenarios":"A directory under pkg/js/libs containing files with two different package names (e.g. package smb and package smbutil), or generated/abandoned files from a rename that kept the old package clause.","commonSituations":"Copy-pasting a new lib file and forgetting to update its package line; leftovers after renaming a module; adding an 'internal' helper file with a different package name into the module dir.","solutions":["Run grep -h '^package ' <dir>/*.go | sort -u — it must yield exactly one name","Fix or move offending files so the directory holds a single package","Re-run bindgen / make devtools-all"],"exampleFix":"# before: dir contains package smb and package smbhelper\n# after: all files in dir declare: package smb","handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"sh\", \"-c\", \"grep -h '^package ' \"+dir+\"/*.go | sort -u\").Output()\nif err != nil || strings.Count(strings.TrimSpace(string(out)), \"\\n\") != 0 {\n    log.Fatalf(\"directory must contain exactly one package: %s\", out)\n}","typeGuard":null,"tryCatchPattern":"Catch the error from CreateTemplateData; when the wrapped text says 'expected 1 package', stop and reconcile package clauses in the directory rather than retrying.","preventionTips":["One package per directory under pkg/js/libs — no exceptions","Watch for rename leftovers: old files keeping the previous package line","Add a CI check that validates single-package dirs before codegen"],"tags":["devtools","bindgen","go-packages","code-generation"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}