gastownhall/beads · error
parse Jira timestamp: %w
Error message
parse Jira timestamp: %w
What it means
FetchIssueTimestamp wraps errors from ParseTimestamp on the issue's "updated" field. It means the JSON parsed fine but the timestamp string (or its absence, yielding "") could not be parsed into a time.Time in the expected Jira format (e.g. 2006-01-02T15:04:05.000-0700). The library throws it because it cannot return a usable sync timestamp from an empty or malformed date.
Source
Thrown at internal/jira/client.go:156
body, err := c.doRequest(ctx, "GET", apiURL, nil)
if err != nil {
return zero, fmt.Errorf("fetch issue %s: %w", jiraKey, err)
}
var result struct {
Fields struct {
Updated string `json:"updated"`
} `json:"fields"`
}
if err := json.Unmarshal(body, &result); err != nil {
return zero, fmt.Errorf("parse Jira response: %w", err)
}
updated, err := ParseTimestamp(result.Fields.Updated)
if err != nil {
return zero, fmt.Errorf("parse Jira timestamp: %w", err)
}
return updated, nil
}
// searchFields is the default set of fields to request in search/get queries.
const searchFields = "summary,description,status,priority,issuetype,project,assignee,labels,created,updated,resolution"
// SearchIssues queries Jira using JQL and returns all matching issues, handling pagination.
func (c *Client) SearchIssues(ctx context.Context, jql string) ([]Issue, error) {
var allIssues []Issue
startAt := 0
nextPageToken := ""
maxResults := 100
page := 0
useV2Pagination := c.APIVersion == "2"
for {View on GitHub (pinned to 71377f2769)
Solutions
- Verify the issue key is correct and the account can see the issue's updated field.
- Log result.Fields.Updated before parsing to inspect the actual value.
- Check ParseTimestamp's accepted layout and extend it if your server emits a different RFC format.
- Confirm the requested fields=updated parameter is honored by your Jira version.
Example fix
// before
updated, err := ParseTimestamp(result.Fields.Updated)
if err != nil {
return zero, fmt.Errorf("parse Jira timestamp: %w", err)
}
// after: distinguish empty timestamp from malformed
if result.Fields.Updated == "" {
return zero, fmt.Errorf("issue %s has no updated timestamp", jiraKey)
}
updated, err := ParseTimestamp(result.Fields.Updated)
if err != nil {
return zero, fmt.Errorf("parse Jira timestamp %q: %w", result.Fields.Updated, err)
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the key format before calling:
var jiraKeyRe = regexp.MustCompile(`^[A-Z][A-Z0-9]*-\d+$`)
func validJiraKey(k string) bool { return jiraKeyRe.MatchString(k) } Type guard
func hasUpdated(fieldsJSON []byte) bool {
var r struct{ Fields struct{ Updated string `json:"updated"` } `json:"fields"` }
if json.Unmarshal(fieldsJSON, &r) != nil { return false }
return r.Fields.Updated != ""
} Try / catch
ts, err := client.FetchIssueTimestamp(ctx, key)
if err != nil {
if strings.Contains(err.Error(), "parse Jira timestamp") {
log.Printf("bad/missing updated timestamp for %s; skipping sync for this issue", key)
return nil // skip rather than fail the whole sync
}
return err
} Prevention
- Validate issue keys against ^[A-Z]+-\d+$ before fetching
- Skip-and-log issues with empty updated fields instead of failing the sync run
- Test ParseTimestamp layouts against both Jira Cloud and Server formats
- Keep field-level permissions in mind when accounts report missing timestamps
When it happens
Trigger: Calling FetchIssueTimestamp on an issue whose "updated" field is missing, null, or formatted unexpectedly (e.g. issue key resolves to a non-issue entity, restricted field, or custom date format).
Common situations: Typo'd or nonexistent issue key that still returns a body; field-level permissions hiding "updated"; Jira Cloud/Server format differences (millisecond and timezone handling); deprecated Jira versions emitting different date formats.
Related errors
- parse Jira response: %w
- pagination limit exceeded: stopped after %d pages
- search issues: %w
- parse search response: %w
- get issue %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5226f56fc2c1526a.
Report an issue: GitHub.