gastownhall/beads · error
building label cache: no cache for primary team %s
Error message
building label cache: no cache for primary team %s
What it means
Returned by Tracker.BatchPush when the primary team has no label cache after the build loop. Creates target the primary team and need its label cache to attach labels, so a missing cache fails the batch before any issue is pushed.
Source
Thrown at internal/linear/tracker.go:329
if primaryCache == nil {
return nil, fmt.Errorf("building state cache: no cache for primary team %s", t.teamIDs[0])
}
teamLabelCaches := make(map[string]*LabelCache, len(t.teamIDs))
for _, teamID := range t.teamIDs {
teamClient := t.clients[teamID]
if teamClient == nil {
continue
}
lc, err := BuildLabelCache(ctx, teamClient)
if err != nil {
return nil, fmt.Errorf("building label cache for team %s: %w", teamID, err)
}
teamLabelCaches[teamID] = lc
}
primaryLabelCache := teamLabelCaches[t.teamIDs[0]]
if primaryLabelCache == nil {
return nil, fmt.Errorf("building label cache: no cache for primary team %s", t.teamIDs[0])
}
result := &tracker.BatchPushResult{}
var toCreate []*types.Issue
var toUpdate []*types.Issue
for _, issue := range issues {
extRef := ""
if issue.ExternalRef != nil {
extRef = *issue.ExternalRef
}
if extRef == "" || !IsLinearExternalRef(extRef) {
toCreate = append(toCreate, issue)
} else {
toUpdate = append(toUpdate, issue)
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Ensure the primary team's client exists before BatchPush (re-run Init/Validate)
- Keep teamIDs and t.clients in sync; register a client for the primary team in tests
- Verify the API key has label-read access to the primary team
- Add a pre-flight check for t.clients[primary] != nil before calling BatchPush
Example fix
// before
teamIDs := []string{"ENG"}; t.SetTeamIDs(teamIDs) // no client for ENG
// after
t.Init(ctx, cfg) // ensures clients (and thus caches) exist for primary team
result, err := t.BatchPush(ctx, issues, nil) Defensive patterns
Strategy: validation
Validate before calling
primary := tracker.PrimaryTeamID()
if primary == "" || tracker.ClientForTeam(primary) == nil {
return errors.New("primary Linear team is not initialized; cannot batch push")
} Try / catch
result, err := tracker.BatchPush(ctx, issues, forceIDs)
if err != nil && strings.Contains(err.Error(), "no cache for primary team") {
// re-init to rebuild clients and caches, then retry once
_ = tracker.Init(ctx, cfg)
result, err = tracker.BatchPush(ctx, issues, forceIDs)
} Prevention
- Initialize the tracker through its Init path so all caches build consistently
- Verify primary-team client existence before any push
- In tests, wire fake clients for the primary team before SetTeamIDs-dependent flows
- Log team/client registration at startup to catch partial initialization early
When it happens
Trigger: BatchPush called where t.teamIDs[0]'s entry was skipped because t.clients[teamIDs[0]] is nil, or BuildLabelCache silently never ran for the primary team — leaving teamLabelCaches[teamIDs[0]] unset.
Common situations: Mirrors the primary-team state-cache failure: partially initialized tracker, primary team client missing, tests that set teamIDs without registering the primary client, credential scoping that excludes the primary team.
Related errors
- building state cache: no cache for primary team %s
- no linear client
- Linear tracker not initialized
- no Linear client available
- loading team labels: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d1b7a235f9cfc12c.
Report an issue: GitHub.