{"record":{"id":"5226f56fc2c1526a","repo":"gastownhall/beads","slug":"parse-jira-timestamp-w","errorCode":null,"errorMessage":"parse Jira timestamp: %w","messagePattern":"parse Jira timestamp: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/jira/client.go","lineNumber":156,"sourceCode":"\n\tbody, err := c.doRequest(ctx, \"GET\", apiURL, nil)\n\tif err != nil {\n\t\treturn zero, fmt.Errorf(\"fetch issue %s: %w\", jiraKey, err)\n\t}\n\n\tvar result struct {\n\t\tFields struct {\n\t\t\tUpdated string `json:\"updated\"`\n\t\t} `json:\"fields\"`\n\t}\n\n\tif err := json.Unmarshal(body, &result); err != nil {\n\t\treturn zero, fmt.Errorf(\"parse Jira response: %w\", err)\n\t}\n\n\tupdated, err := ParseTimestamp(result.Fields.Updated)\n\tif err != nil {\n\t\treturn zero, fmt.Errorf(\"parse Jira timestamp: %w\", err)\n\t}\n\n\treturn updated, nil\n}\n\n// searchFields is the default set of fields to request in search/get queries.\nconst searchFields = \"summary,description,status,priority,issuetype,project,assignee,labels,created,updated,resolution\"\n\n// SearchIssues queries Jira using JQL and returns all matching issues, handling pagination.\nfunc (c *Client) SearchIssues(ctx context.Context, jql string) ([]Issue, error) {\n\tvar allIssues []Issue\n\tstartAt := 0\n\tnextPageToken := \"\"\n\tmaxResults := 100\n\tpage := 0\n\tuseV2Pagination := c.APIVersion == \"2\"\n\n\tfor {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/jira/client.go#L138-L174","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nupdated, err := ParseTimestamp(result.Fields.Updated)\nif err != nil {\n    return zero, fmt.Errorf(\"parse Jira timestamp: %w\", err)\n}\n// after: distinguish empty timestamp from malformed\nif result.Fields.Updated == \"\" {\n    return zero, fmt.Errorf(\"issue %s has no updated timestamp\", jiraKey)\n}\nupdated, err := ParseTimestamp(result.Fields.Updated)\nif err != nil {\n    return zero, fmt.Errorf(\"parse Jira timestamp %q: %w\", result.Fields.Updated, err)\n}","handlingStrategy":"validation","validationCode":"// Validate the key format before calling:\nvar jiraKeyRe = regexp.MustCompile(`^[A-Z][A-Z0-9]*-\\d+$`)\nfunc validJiraKey(k string) bool { return jiraKeyRe.MatchString(k) }","typeGuard":"func hasUpdated(fieldsJSON []byte) bool {\n    var r struct{ Fields struct{ Updated string `json:\"updated\"` } `json:\"fields\"` }\n    if json.Unmarshal(fieldsJSON, &r) != nil { return false }\n    return r.Fields.Updated != \"\"\n}","tryCatchPattern":"ts, err := client.FetchIssueTimestamp(ctx, key)\nif err != nil {\n    if strings.Contains(err.Error(), \"parse Jira timestamp\") {\n        log.Printf(\"bad/missing updated timestamp for %s; skipping sync for this issue\", key)\n        return nil // skip rather than fail the whole sync\n    }\n    return err\n}","preventionTips":["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"],"tags":["jira","timestamp","date-parsing","go"],"backgroundTag":"invalid-timestamp-format","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}