gastownhall/beads · warning

repository already configured: %s

Error message

repository already configured: %s

What it means

AddRepo rejects adding a repository path that is already present in repos.additional in config.yaml. The error message includes the duplicate path. This is an intentional idempotency guard, not a failure of the file operation.

Source

Thrown at internal/config/repos.go:214

}

// AddRepo adds a repository to the repos.additional list in config.yaml
// If primary is not set, it defaults to "."
func AddRepo(configPath, repoPath string) error {
	repos, err := GetReposFromYAML(configPath)
	if err != nil {
		return fmt.Errorf("failed to get repos config: %w", err)
	}

	// Set primary to "." if not already set (standard multi-repo convention)
	if repos.Primary == "" {
		repos.Primary = "."
	}

	// Check if repo already exists
	for _, existing := range repos.Additional {
		if existing == repoPath {
			return fmt.Errorf("repository already configured: %s", repoPath)
		}
	}

	// Add the new repo
	repos.Additional = append(repos.Additional, repoPath)

	return SetReposInYAML(configPath, repos)
}

// RemoveRepo removes a repository from the repos.additional list in config.yaml
func RemoveRepo(configPath, repoPath string) error {
	repos, err := GetReposFromYAML(configPath)
	if err != nil {
		return fmt.Errorf("failed to get repos config: %w", err)
	}

	// Find and remove the repo
	found := false

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the existing list first: `bd repo list` or read config.yaml before adding
  2. Skip the call if the repo is already present, or treat this error as success (idempotent add)
  3. Use the exact same path string to detect duplicates yourself before calling
  4. Remove the duplicate entry manually if the list got into a bad state

Example fix

// before
repos, _ := GetReposFromYAML(cfg)
if !slices.Contains(repos.Additional, p) {
    AddRepo(cfg, p)
}
// after — or simply treat as idempotent
if err := AddRepo(cfg, p); err != nil && !strings.Contains(err.Error(), "already configured") {
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

repos, err := GetReposFromYAML(configPath)
if err == nil && slices.Contains(repos.Additional, repoPath) {
    return nil // already added; skip
}

Try / catch

if err := AddRepo(cfgPath, repoPath); err != nil {
    if strings.Contains(err.Error(), "already configured") {
        return nil // treat as idempotent success
    }
    return err
}

Prevention

When it happens

Trigger: AddRepo(configPath, repoPath) is called and the exact string repoPath already exists in the repos.additional list (exact string comparison, no path normalization).

Common situations: Running `bd repo add` twice for the same directory; adding a repo whose path string matches an existing entry (e.g. same path with different casing or trailing slash counts as different — but identical strings collide).

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/749304659e9fca14. Report an issue: GitHub.