gastownhall/beads · error

failed to search issues by description: %w

Error message

failed to search issues by description: %w

What it means

FindIssueByDescriptionContains issues a GraphQL query filtering issues by description substring. Any failure from c.Execute — transport, HTTP status, or GraphQL-level error — is wrapped with this message so the caller knows the description search itself failed (distinct from 'no match found', which returns nil, nil).

Source

Thrown at internal/linear/client.go:781

			"id": map[string]interface{}{
				"eq": c.TeamID,
			},
		},
		"description": map[string]interface{}{
			"contains": text,
		},
	}

	req := &GraphQLRequest{
		Query: query,
		Variables: map[string]interface{}{
			"filter": filter,
		},
	}

	data, err := c.Execute(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to search issues by description: %w", err)
	}

	var issuesResp IssuesResponse
	if err := json.Unmarshal(data, &issuesResp); err != nil {
		return nil, fmt.Errorf("failed to parse description search response: %w", err)
	}

	if len(issuesResp.Issues.Nodes) > 0 {
		return &issuesResp.Issues.Nodes[0], nil
	}
	return nil, nil
}

// issueCreateMutation is the GraphQL mutation for creating a Linear issue.
const issueCreateMutation = `
	mutation CreateIssue($input: IssueCreateInput!) {
		issueCreate(input: $input) {
			success

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the cause with errors.As/Is to find the root transport or GraphQL error and fix that specifically.
  2. Validate the API key with a `viewer { id }` query.
  3. If the cause is 429, retry with backoff respecting Linear's rate-limit headers.
  4. If the cause is a GraphQL validation error, compare the filter payload against the current Linear schema.

Example fix

// before
if err != nil {
    return nil, fmt.Errorf("failed to search issues by description: %w", err)
}
// after
if err != nil {
    if isTransient(err) {
        return nil, RetryableError{fmt.Errorf("failed to search issues by description: %w", err)}
    }
    return nil, fmt.Errorf("failed to search issues by description: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if apiKey == "" {
    return errors.New("Linear API key missing; cannot search issues")
}
if description == "" {
    return errors.New("empty description substring; search would be meaningless")
}

Try / catch

issue, err := client.FindIssueByDescriptionContains(ctx, desc)
if err != nil {
    if isRetryable(err) { // 429, timeout, 5xx
        issue, err = retryWithBackoff(3, func() (*linear.Issue, error) {
            return client.FindIssueByDescriptionContains(ctx, desc)
        })
    }
    if err != nil {
        return fmt.Errorf("dedupe check failed: %w", err)
    }
}

Prevention

When it happens

Trigger: Execute fails while running the description-contains filter query: network error, invalid API key (401), rate limit (429), or a GraphQL validation error such as an invalid `filter` structure sent to the Linear API.

Common situations: Expired LINEAR_API_KEY, transient network outage during idempotent issue creation (CreateIssueIdempotent) or after an ambiguous batch (recoverAfterAmbiguousBatch), Linear API schema changes invalidating the filter input shape.

Related errors


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