gastownhall/beads · error
repos section is not a map
Error message
repos section is not a map
What it means
GetReposFromYAML expects the top-level `repos` key in config.yaml to be a mapping (with optional `primary` and `additional` keys). When `repos:` parses to something else — a string, number, or list — the type assertion to map[string]interface{} fails and this error is returned.
Source
Thrown at internal/config/repos.go:54
data, err := os.ReadFile(configPath) // #nosec G304 - config file path from caller
if err != nil {
if os.IsNotExist(err) {
return &ReposConfig{}, nil
}
return nil, fmt.Errorf("failed to read config.yaml: %w", err)
}
// Parse into a generic map to extract repos section
var cfg map[string]interface{}
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to parse config.yaml: %w", err)
}
repos := &ReposConfig{}
if reposRaw, ok := cfg["repos"]; ok && reposRaw != nil {
reposMap, ok := reposRaw.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("repos section is not a map")
}
if primary, ok := reposMap["primary"].(string); ok {
repos.Primary = primary
}
if additional, ok := reposMap["additional"]; ok && additional != nil {
switch v := additional.(type) {
case []interface{}:
for _, item := range v {
if str, ok := item.(string); ok {
repos.Additional = append(repos.Additional, str)
}
}
}
}
}
View on GitHub (pinned to 71377f2769)
Solutions
- Restructure the repos section as a mapping with primary/additional keys.
- Example correct shape: repos:\n primary: "."\n additional: ["../other-repo"].
- Re-run the command after fixing; or delete the repos key and let `bd repo add` regenerate it.
Example fix
// before
repos: ../other-repo
// after
repos:
primary: "."
additional:
- "../other-repo" Defensive patterns
Strategy: type-guard
Validate before calling
var cfg map[string]interface{}
if data, err := os.ReadFile(configPath); err == nil {
if yaml.Unmarshal(data, &cfg) == nil {
if raw, ok := cfg["repos"]; ok && raw != nil {
if _, ok := raw.(map[string]interface{}); !ok {
return fmt.Errorf("repos must be a mapping with primary/additional keys")
}
}
}
} Type guard
func reposIsMap(cfg map[string]interface{}) bool {
raw, ok := cfg["repos"]
if !ok || raw == nil { return true }
_, ok = raw.(map[string]interface{})
return ok
} Try / catch
repos, err := config.GetReposFromYAML(configPath)
if err != nil && strings.Contains(err.Error(), "repos section is not a map") {
return fmt.Errorf("fix `repos:` in %s to a mapping: repos:\\n primary: ...", configPath)
} Prevention
- Nest primary/additional under repos:; never put a value directly after repos:.
- Use `bd repo add`/`bd repo remove` instead of hand-editing the repos section.
- Keep a schema example of config.yaml in your project docs.
When it happens
Trigger: Calling GetReposFromYAML (via AddRepo/RemoveRepo/ListRepos) with a config.yaml containing e.g. `repos: foo`, `repos: [a, b]`, or `repos: 3` instead of `repos:\n primary: ...\n additional: [...]`.
Common situations: Hand-editing the config and writing the repo path directly under `repos:` instead of nesting it; misreading the schema and using a list of repos; a malformed merge that flattened the section.
Related errors
- persist sync.remote to config.yaml: %w
- failed to persist sync.remote to config.yaml: %w
- failed to persist sync.remote to config.yaml: %v
- failed to configure hydration: %w
- error reading config file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c46dab778cba8de4.
Report an issue: GitHub.