{"record":{"id":"5afb2956d4c58aa5","repo":"wtfutil/wtf","slug":"error-fetching-user-s","errorCode":null,"errorMessage":"error fetching user: %s","messagePattern":"error fetching user: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/asana/client.go","lineNumber":215,"sourceCode":"\t\tassignee:    assignString,\n\t}\n\n\treturn taskItem\n\n}\n\nfunc getOtherUserEmail(client *asana.Client, uid string) (string, error) {\n\tif uid == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing uid\")\n\t}\n\n\tu := &asana.User{\n\t\tID: uid,\n\t}\n\n\terr := u.Fetch(client, nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error fetching user: %s\", err)\n\t}\n\n\treturn u.Email, nil\n}\n\nfunc getCurrentUserId(client *asana.Client, mode string) (string, error) {\n\tif strings.HasSuffix(mode, \"_all\") {\n\t\treturn \"\", nil\n\t}\n\tu, err := client.CurrentUser()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error getting current user: %s\", err)\n\t}\n\n\treturn u.ID, nil\n}\n\nfunc findSection(client *asana.Client, project *asana.Project, sectionName string) (string, error) {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/asana/client.go#L197-L233","documentation":"Returned by getOtherUserEmail when asana.User.Fetch fails for the given user GID. After passing the empty-uid guard, the library fetches the user to obtain their email; any API error (unknown GID, permissions, network, rate limit) is wrapped with this message.","triggerScenarios":"Calling getOtherUserEmail with a uid that is not a valid/accessible Asana user GID: user deactivated or removed from the workspace, GID truncated/mistyped, token lacking visibility of that user, or a transient API/network failure during u.Fetch(client, nil).","commonSituations":"Task assigned to a user who has since left the workspace (deactivated accounts remain on old tasks); malformed uid parsed from task data; token from a guest account that cannot see other members' profiles.","solutions":["Verify the user GID exists and is active: GET /users/<gid> with the same token.","Handle deactivated/removed users gracefully — treat missing users as an empty email instead of failing the whole fetch.","Confirm the token's account can see the other user (guest tokens often cannot list workspace members).","Retry on transient network/5xx errors surfaced in the wrapped message."],"exampleFix":"// before\nerr := u.Fetch(client, nil)\nif err != nil {\n    return \"\", fmt.Errorf(\"error fetching user: %s\", err)\n}\n// after\nerr := u.Fetch(client, nil)\nif err != nil {\n    return \"\", fmt.Errorf(\"error fetching user %s: %w\", uid, err)\n}","handlingStrategy":"try-catch","validationCode":"if uid == \"\" {\n    return fmt.Errorf(\"skip: empty user id\")\n}\n// optionally pre-check visibility: GET /users/<gid> succeeds with the same token","typeGuard":"func validUserID(uid string) bool {\n    return uid != \"\" && len(uid) >= 5\n}","tryCatchPattern":"email, err := getOtherUserEmail(client, uid)\nif err != nil {\n    log.Printf(\"could not fetch user %s (may be deactivated or hidden): %v\", uid, err)\n    email = \"\" // degrade gracefully instead of failing the whole fetch\n}","preventionTips":["Handle deactivated users: old tasks keep assignees who left the workspace.","Use a full-member token, not a guest token, so other users' profiles are visible.","Validate user GIDs sourced from task data before fetching.","Log and skip individual user lookups rather than aborting the entire task fetch."],"tags":["asana","api","user","fetch","error-wrapping"],"backgroundTag":"asana-user-not-found","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"}