{"record":{"id":"debbee363fc2972c","repo":"gastownhall/beads","slug":"failed-to-parse-create-project-response-w","errorCode":null,"errorMessage":"failed to parse create project response: %w","messagePattern":"failed to parse create project response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1539,"sourceCode":"\tif state != \"\" {\n\t\tinput[\"state\"] = state\n\t}\n\n\treq := &GraphQLRequest{\n\t\tQuery: query,\n\t\tVariables: map[string]interface{}{\n\t\t\t\"input\": input,\n\t\t},\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create project: %w\", err)\n\t}\n\n\tvar createResp ProjectCreateResponse\n\tif err := json.Unmarshal(data, &createResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse create project response: %w\", err)\n\t}\n\n\tif !createResp.ProjectCreate.Success {\n\t\treturn nil, fmt.Errorf(\"project creation reported as unsuccessful\")\n\t}\n\n\treturn &createResp.ProjectCreate.Project, nil\n}\n\n// UpdateProject updates an existing project in Linear.\nfunc (c *Client) UpdateProject(ctx context.Context, projectID string, updates map[string]interface{}) (*Project, error) {\n\tquery := `\n\t\tmutation UpdateProject($id: String!, $input: ProjectUpdateInput!) {\n\t\t\tprojectUpdate(id: $id, input: $input) {\n\t\t\t\tsuccess\n\t\t\t\tproject {\n\t\t\t\t\tid\n\t\t\t\t\tname","sourceCodeStart":1521,"sourceCodeEnd":1557,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L1521-L1557","documentation":"After the projectCreate mutation executes successfully, CreateProject unmarshals the response into ProjectCreateResponse. This error wraps json.Unmarshal failure — the body doesn't match {projectCreate:{success,project:{...}}}. It separates decode failures from request failures and from the explicit success=false case.","triggerScenarios":"c.Execute returned HTTP-200 data not matching ProjectCreateResponse: GraphQL errors envelope instead of data (mutation rejected but surfaced as errors payload), gateway error JSON, or the ProjectCreateResponse/Project structs drifted from the Linear schema (missing project field, wrong types).","commonSituations":"Struct definition out of date after a Linear API change; proxy returning a JSON error body; response where projectCreate exists but project is null with different shape than the struct expects.","solutions":["Dump the raw `data` bytes to inspect the actual response.","Check for a top-level \"errors\" array — the mutation likely failed and the error message is there.","Compare ProjectCreateResponse and nested Project fields against the current Linear GraphQL schema; fix field names/types.","Test the same mutation manually (curl/Altair) to confirm the expected shape.","Update the client code or library version to match the current API schema."],"exampleFix":"// before\nvar createResp ProjectCreateResponse\nif err := json.Unmarshal(data, &createResp); err != nil { return nil, err }\n// after\nvar probe struct{ Errors []struct{ Message string `json:\"message\"` } `json:\"errors\"` }\nif json.Unmarshal(data, &probe) == nil && len(probe.Errors) > 0 {\n    return nil, fmt.Errorf(\"projectCreate failed: %s\", probe.Errors[0].Message)\n}\nvar createResp ProjectCreateResponse\nif err := json.Unmarshal(data, &createResp); err != nil { return nil, err }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isProjectCreateResponse(data []byte) bool {\n    var probe struct {\n        ProjectCreate *struct {\n            Success bool              `json:\"success\"`\n            Project json.RawMessage   `json:\"project\"`\n        } `json:\"projectCreate\"`\n    }\n    return json.Unmarshal(data, &probe) == nil && probe.ProjectCreate != nil\n}","tryCatchPattern":"project, err := client.CreateProject(ctx, name, desc, state)\nif err != nil {\n    var ute *json.UnmarshalTypeError\n    if errors.As(err, &ute) {\n        return fmt.Errorf(\"projectCreate payload mismatch at %s — verify Linear schema\", ute.Field)\n    }\n    return err\n}","preventionTips":["Check for a GraphQL \"errors\" key before unmarshalling into the typed response.","Keep ProjectCreateResponse fields minimal and matching the mutation's selection set exactly.","Add an integration test that creates (and cleans up) a project to catch drift.","Log raw response bodies when decode errors occur."],"tags":["go","json","unmarshal","mutation","linear-api"],"backgroundTag":"response-unmarshal-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}