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

  1. Move one of the conflicting packages' files into its own directory (Go convention: one package per directory)
  2. Rename the test files' package to match the primary package (e.g. package foo for in-package tests)
  3. If intentional, pass/exclude those files so the bundler only sees one package
  4. 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

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


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)