{"record":{"id":"ac2cf39df0d01a16","repo":"gastownhall/beads","slug":"failed-to-parse-work-item-response-w","errorCode":null,"errorMessage":"failed to parse work item response: %w","messagePattern":"failed to parse work item response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/gitlab/client.go","lineNumber":624,"sourceCode":"\t\treturn nil, err\n\t}\n\n\tvar resp struct {\n\t\tWorkItemCreate struct {\n\t\t\tErrors   []string `json:\"errors\"`\n\t\t\tWorkItem *struct {\n\t\t\t\tID     string `json:\"id\"`\n\t\t\t\tIID    string `json:\"iid\"`\n\t\t\t\tTitle  string `json:\"title\"`\n\t\t\t\tWebURL string `json:\"webUrl\"`\n\t\t\t\tType   struct {\n\t\t\t\t\tName string `json:\"name\"`\n\t\t\t\t} `json:\"workItemType\"`\n\t\t\t} `json:\"workItem\"`\n\t\t} `json:\"workItemCreate\"`\n\t}\n\tif err := json.Unmarshal(data, &resp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse work item response: %w\", err)\n\t}\n\tif len(resp.WorkItemCreate.Errors) > 0 {\n\t\treturn nil, fmt.Errorf(\"work item creation failed: %s\", resp.WorkItemCreate.Errors[0])\n\t}\n\tif resp.WorkItemCreate.WorkItem == nil {\n\t\treturn nil, fmt.Errorf(\"work item creation returned nil\")\n\t}\n\n\twi := resp.WorkItemCreate.WorkItem\n\treturn &WorkItem{\n\t\tID:    wi.ID,\n\t\tIID:   wi.IID,\n\t\tTitle: wi.Title,\n\t\tType:  wi.Type.Name,\n\t}, nil\n}\n\n// GetWorkItemGID looks up the global ID of a work item by its project-scoped IID.","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/gitlab/client.go#L606-L642","documentation":"CreateTaskWorkItem got valid JSON back from the GraphQL workItemCreate mutation, but the payload could not be unmarshaled into the expected nested response struct (workItemCreate.workItem.workItemType etc.). The mutation may have returned an error-shaped body or a schema different from what the client expects.","triggerScenarios":"Calling CreateTaskWorkItem where the mutation response omits or restructures fields the struct expects — e.g. workItemType removed/renamed in a GitLab upgrade, or the response being a GraphQL errors envelope whose shape mismatches resp.Data after graphqlRequest returns only result.Data.","commonSituations":"GitLab minor-version schema drift on workItemCreate; the mutation returning data:null with errors (unmarshaled into zeroed struct, but here a type mismatch such as a string where an object is expected); querying an instance where work items are disabled.","solutions":["Log the raw GraphQL data payload to compare against the expected struct shape.","Verify the GitLab version's workItemCreate mutation schema matches the client's struct.","Check whether the response contains data:null plus errors — handle before unmarshaling into the nested struct.","Update the client's response struct to match the instance's GraphQL schema (introspect with a GraphQL IDE)."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// introspect the instance schema before relying on workItemCreate\nconst q = `{ __type(name: \"WorkItemCreatePayload\") { fields { name } } }`","typeGuard":null,"tryCatchPattern":"item, err := client.CreateTaskWorkItem(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to parse work item response\") {\n        // schema drift: log raw payload, refresh client struct or pin GitLab version\n    }\n    return err\n}","preventionTips":["Pin the GitLab instance version and test the client against it in CI.","Re-run schema introspection after GitLab upgrades.","Keep response structs minimal — only fields actually consumed reduce drift risk."],"tags":["gitlab","graphql","json","parse-error","schema-mismatch"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}