{"record":{"id":"36594d25c094e7b0","repo":"wtfutil/wtf","slug":"failed-to-extract-account-id-from-converted-query","errorCode":null,"errorMessage":"failed to extract account ID from converted query: %s","messagePattern":"failed to extract account ID from converted query: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/jira/client.go","lineNumber":149,"sourceCode":"\t}\n\n\tvar conversionResult JQLConversionResponse\n\terr = utils.ParseJSON(&conversionResult, bytes.NewReader(resp))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(conversionResult.QueryStrings) == 0 {\n\t\treturn \"\", fmt.Errorf(\"no conversion result for username: %s\", username)\n\t}\n\n\t// Return the converted JQL query part (just the assignee part)\n\tconvertedQuery := conversionResult.QueryStrings[0].ConvertedQuery\n\n\t// Extract account ID properly\n\taccountID := extractAccountIDFromJQL(convertedQuery)\n\tif accountID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"failed to extract account ID from converted query: %s\", convertedQuery)\n\t}\n\n\t// Cache the result for 10 minutes\n\tuserIDCache.Set(username, accountID, 10*time.Minute)\n\n\treturn convertedQuery, nil\n}\n\n// extractAccountIDFromJQL extracts the account ID from a converted JQL query\nfunc extractAccountIDFromJQL(jql string) string {\n\t// Example: \"assignee = \\\"account:5b10ac8d82e05b22cc7d4ef5\\\"\"\n\t// We want to extract: \"account:5b10ac8d82e05b22cc7d4ef5\"\n\n\tstart := strings.Index(jql, \"\\\"\")\n\tif start == -1 {\n\t\treturn \"\"\n\t}\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/jira/client.go#L131-L167","documentation":"After obtaining the converted JQL query, ConvertJQLWithUsername runs extractAccountIDFromJQL to pull the account ID out of the assignee clause. If the converted query contains no recognizable account ID (e.g. 'accountID in (\"...\")' pattern doesn't match), it refuses to cache and fails, since caching a wrong/empty mapping would poison later requests.","triggerScenarios":"Jira's pdcleaner returns a ConvertedQuery whose assignee clause doesn't contain the account-ID pattern the regex expects - e.g. it returns the original username form or a differently formatted clause.","commonSituations":"Jira Cloud API response format drift (new API versions changing the accountID clause), users resolved via email rather than account ID, usernames that map to group-like clauses, custom forks altering extractAccountIDFromJQL.","solutions":["Update extractAccountIDFromJQL's regex to match the current Jira pdcleaner response format","Log the convertedQuery from the error to see the actual clause returned","Check for Jira API changelog notes about /rest/api/3/jql/pdcleaner output changes","Fall back to resolving the account ID via /rest/api/3/user/query instead"],"exampleFix":"// before\nre := regexp.MustCompile(`accountID in \\(\"([^\"]+)\"\\)`)\n// after (tolerate optional spaces / multiple ids)\nre := regexp.MustCompile(`accountID\\s+in\\s+\\(\"([^\"]+)\"`)","handlingStrategy":"validation","validationCode":"// verify the converted clause actually embeds an account ID\nvar accountIDRe = regexp.MustCompile(`accountID\\s+in\\s+\\(\"[^\"]+\"`)\nif !accountIDRe.MatchString(convertedQuery) {\n    return fmt.Errorf(\"converted query lacks account ID: %s\", convertedQuery)\n}","typeGuard":"func hasAccountID(q string) bool {\n    return extractAccountIDFromJQL(q) != \"\"\n}","tryCatchPattern":"query, err := widget.ConvertJQLWithUsername(username)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to extract account ID\") {\n        log.Printf(\"Jira pdcleaner format changed; inspect converted query in msg: %v\", err)\n    }\n    return err\n}","preventionTips":["Pin-test extractAccountIDFromJQL against real pdcleaner responses in CI","Log the converted query when extraction fails to detect format drift","Track Atlassian API changelog for /jql/pdcleaner changes","Prefer resolving account IDs via /rest/api/3/user/query as a backup"],"tags":["jira","regex","parsing","go"],"backgroundTag":"missing-account-id","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}