gastownhall/beads · error

parse create response: %w

Error message

parse create response: %w

What it means

CreateIssue wraps json.Unmarshal errors for the POST /issue response. The issue was likely created (2xx) but the body — expected to contain id, key, self — could not be decoded, usually because it's HTML or an unexpected envelope. The library throws it because it needs created.Key to fetch the full issue.

Source

Thrown at internal/jira/client.go:275

	if err != nil {
		return nil, fmt.Errorf("marshal create request: %w", err)
	}

	apiURL := fmt.Sprintf("%s/issue", c.apiBase())

	body, err := c.doRequest(ctx, "POST", apiURL, data)
	if err != nil {
		return nil, fmt.Errorf("create issue: %w", err)
	}

	// Create response only returns id, key, self. Fetch the full issue.
	var created struct {
		ID   string `json:"id"`
		Key  string `json:"key"`
		Self string `json:"self"`
	}
	if err := json.Unmarshal(body, &created); err != nil {
		return nil, fmt.Errorf("parse create response: %w", err)
	}

	return c.GetIssue(ctx, created.Key)
}

// UpdateIssue updates an existing Jira issue by key.
func (c *Client) UpdateIssue(ctx context.Context, key string, fields map[string]interface{}) error {
	payload := map[string]interface{}{"fields": fields}
	data, err := json.Marshal(payload)
	if err != nil {
		return fmt.Errorf("marshal update request: %w", err)
	}

	apiURL := fmt.Sprintf("%s/issue/%s", c.apiBase(), url.PathEscape(key))

	_, err = c.doRequest(ctx, "PUT", apiURL, data)
	if err != nil {
		return fmt.Errorf("update issue %s: %w", key, err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the raw body to confirm whether it's an HTML page or a differently-shaped JSON success object.
  2. Before retrying CreateIssue, search Jira by summary/project to avoid creating duplicates.
  3. Remove proxy/SSO interception for API routes or bypass the gateway for REST calls.
  4. Parse defensively: attempt to extract "key" even if the full struct doesn't match.

Example fix

// before
if err := json.Unmarshal(body, &created); err != nil {
    return nil, fmt.Errorf("parse create response: %w", err)
}
// after: log body and warn that the issue may exist
if err := json.Unmarshal(body, &created); err != nil {
    return nil, fmt.Errorf("parse create response: %w (issue may have been created; body: %.200s)", err, string(body))
}
Defensive patterns

Strategy: try-catch

Validate before calling

func isJSONBody(b []byte) bool {
    s := bytes.TrimLeft(b, " \t\r\n")
    return len(s) > 0 && (s[0] == '{' || s[0] == '[')
}

Type guard

func createResponseUsable(b []byte) bool {
    var c struct{ Key string `json:"key"` }
    return json.Unmarshal(b, &c) == nil && c.Key != ""
}

Try / catch

issue, err := client.CreateIssue(ctx, fields)
if err != nil && strings.Contains(err.Error(), "parse create response") {
    // Issue was likely created; DO NOT blindly retry (duplicate risk).
    // Search by summary to locate or confirm the created issue:
    found, serr := client.SearchIssues(ctx, fmt.Sprintf("project = %s AND summary ~ %q ORDER BY created DESC", projectKey, summary))
    if serr == nil && len(found) > 0 {
        issue = &found[0]
        err = nil
    }
}

Prevention

When it happens

Trigger: POST /issue returns 2xx with a non-JSON or unexpected body: proxy/SSO HTML injected after success, gateway response wrappers, or an API version whose create response schema differs.

Common situations: Corporate proxies rewriting successful responses; custom Jira apps altering create responses; mistyped base URL that happens to accept POST but returns HTML; truncated response bodies on flaky connections. Danger: the issue exists but the caller never learns its key, risking duplicates on retry.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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