gastownhall/beads · critical
no linear client
Error message
no linear client
What it means
BuildLabelCache requires a non-nil *Client to call GetTeamLabels. This guard error fires immediately when a nil client is passed, before any network call is made. It indicates a wiring/initialization bug in the caller, not a Linear API problem.
Source
Thrown at internal/linear/mapping.go:485
case types.StatusBlocked:
return "started" // Linear doesn't have blocked state type
case types.StatusClosed:
return "completed"
default:
return "unstarted"
}
}
// LabelCache maps normalized Linear label names (lowercase) to Linear label IDs
// for a single team.
type LabelCache struct {
IDByLowerName map[string]string
}
// BuildLabelCache fetches team labels and indexes them by lowercase trimmed name.
func BuildLabelCache(ctx context.Context, client *Client) (*LabelCache, error) {
if client == nil {
return nil, fmt.Errorf("no linear client")
}
labels, err := client.GetTeamLabels(ctx)
if err != nil {
return nil, err
}
c := &LabelCache{
IDByLowerName: make(map[string]string, len(labels)),
}
for _, lb := range labels {
k := strings.ToLower(strings.TrimSpace(lb.Name))
if k != "" && lb.ID != "" {
c.IDByLowerName[k] = lb.ID
}
}
return c, nil
}
// IssueTypeToLinearLabelLookupKey returns the label_type_map key (lowercase) forView on GitHub (pinned to 71377f2769)
Solutions
- Initialize the Linear client before calling BuildLabelCache (e.g. linear.NewClient(token)) and check its constructor error.
- Add a nil check on the client at the call site (CreateIssue/UpdateIssue/BatchPush) and fail fast with a clear config error.
- Fix any constructor path that can return (nil, nil) so callers never hold a nil client.
- In tests, pass a stubbed *Client or test the cache-building logic via an interface.
Example fix
// before
cache, err := linear.BuildLabelCache(ctx, client) // client is nil
// after
if client == nil {
return fmt.Errorf("linear client not initialized; check config/token loading")
}
cache, err := linear.BuildLabelCache(ctx, client) Defensive patterns
Strategy: validation
Validate before calling
if client == nil {
return fmt.Errorf("linear client not initialized")
}
cache, err := linear.BuildLabelCache(ctx, client) Type guard
func hasLinearClient(c *linear.Client) bool { return c != nil } Prevention
- Construct the Linear client once at startup and fail fast if its constructor errors.
- Never return (nil, nil) from client factory functions.
- Add a unit test asserting BuildLabelCache is only reachable with a non-nil client.
When it happens
Trigger: Calling linear.BuildLabelCache(ctx, nil), typically because an enclosing struct's client field was never initialized or a factory returned nil without error propagation.
Common situations: Lazy client construction skipped when config load partially failed; a *Client variable left nil on an error path that returned nil, nil; tests constructing mapping helpers without a stub client.
Related errors
- Linear tracker not initialized
- no Linear client available
- %w. Hint: run 'bd init' to create a database in the current
- no store available
- no database connection
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/135f6b4010f02af7.
Report an issue: GitHub.