github/copilot-sdk · error
multiple packages and found in
Error message
multiple packages %q and %q found in %q
What it means
detectPackageName requires all .go files in a directory to belong to a single package (ignoring _test files per its logic). When a second, different package name is seen it abandons detection, falls back to defaultPackageName, and reports the two conflicting names. Mixed-package directories are not supported by the bundler.
Solutions
- Move one of the conflicting packages' files into its own directory (Go convention: one package per directory)
- Rename the test files' package to match the primary package (e.g. package foo for in-package tests)
- If intentional, pass/exclude those files so the bundler only sees one package
- Accept the fallback: the bundler proceeds with defaultPackageName, but prefer fixing the directory layout
Example fix
// before: pkg/util/client.go (package util) and pkg/util/helpers_test.go (package util_test) // after: move tests or unify // -package util_test // +package util
Defensive patterns
Strategy: validation
Validate before calling
pkgs, err := parser.ParseDir(token.NewFileSet(), dir, nil, parser.PackageClauseOnly)
if err == nil && len(pkgs) > 1 {
return fmt.Errorf("directory %s mixes packages: %v", dir, keys(pkgs))
} Try / catch
if err := bundle(dir); err != nil && strings.Contains(err.Error(), "multiple packages") {
// fall back to bundling a single-package subdirectory instead
} Prevention
- Follow the one-package-per-directory convention
- Name test files package foo (in-package tests) rather than foo_test when co-located
- Keep generated files in their own package directories
When it happens
Trigger: The bundled directory contains files from two different packages, e.g. both `package foo` and `package foo_test` or `package main` mixed with a library package, so the second file's name mismatches the first.
Common situations: Test helper files dropped into a library package directory; accidentally generated files with a different package header; hand-merging files from other packages into one folder.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- no Go package found in
- failed to parse package clause in
- CopilotClientOptions.
- SessionFS.InitialWorkingDirectory is required
- SessionFS.SessionStatePath is required
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/2e634cef536d9358.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:251
if err != nil {
return defaultPackageName, fmt.Errorf("failed to evaluate build constraints in %q: %w", filepath.Join(dir, name), err)
}
if !matches {
continue
}
path := filepath.Join(dir, name)
file, err := parser.ParseFile(token.NewFileSet(), path, nil, parser.PackageClauseOnly)
if err != nil {
return defaultPackageName, fmt.Errorf("failed to parse package clause in %q: %w", path, err)
}
if packageName == "" {
packageName = file.Name.Name
continue
}
if packageName != file.Name.Name {
return defaultPackageName, fmt.Errorf("multiple packages %q and %q found in %q", packageName, file.Name.Name, dir)
}
}
if packageName == "" {
return defaultPackageName, fmt.Errorf("no Go package found in %q", dir)
}
return packageName, nil
}
// detectCLIVersion detects the CLI version by:
// 1. Running "go list -m" to get the copilot-sdk version from the user's go.mod
// 2. Fetching package.json from the SDK repo at that version
// 3. Extracting the pinned Copilot CLI version from it
func detectCLIVersion() (string, error) {
// Get the SDK version from the user's go.mod
sdkVersion, err := getSDKVersion()
if err != nil {
return "", fmt.Errorf("failed to get SDK version: %w", err)View on GitHub (pinned to cd8cf15dc3)