gastownhall/beads · error
project creation reported as unsuccessful
Error message
project creation reported as unsuccessful
What it means
CreateProject checks the mutation payload's projectCreate.success boolean after a successful transport call and decode. When Linear reports success=false (with no GraphQL-level error and no unmarshal failure), the library returns this sentinel error. It means Linear accepted and answered the mutation but indicated the project was not created.
Solutions
- Since this error carries no detail, log the full createResp (or raw data) around the call to see what else the payload contains.
- Verify the API token's write permissions for the target team in Linear admin settings.
- Confirm teamIds is valid — cross-check c.TeamID with FetchTeams.
- Run the identical projectCreate mutation manually (curl/Altair) with the same input to see Linear's full response.
- If the payload contains a null project with success=false, check Linear's API changelog for changed projectCreate semantics and update the response struct.
Example fix
// before
if !createResp.ProjectCreate.Success {
return nil, fmt.Errorf("project creation reported as unsuccessful")
}
// after (caller side: log payload for diagnosis)
project, err := client.CreateProject(ctx, name, desc, state)
if err != nil && err.Error() == "project creation reported as unsuccessful" {
log.Printf("linear rejected projectCreate for team=%s name=%q; check token scopes/teamId", client.TeamID, name)
} Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm team and write access before attempting creation
teams, err := client.FetchTeams(ctx)
if err != nil { return err }
found := false
for _, t := range teams {
if t.ID == client.TeamID { found = true; break }
}
if !found {
return fmt.Errorf("TeamID %q not visible to this token", client.TeamID)
} Type guard
func createSucceeded(resp ProjectCreateResponse) bool {
return resp.ProjectCreate.Success && resp.ProjectCreate.Project.ID != ""
} Try / catch
project, err := client.CreateProject(ctx, name, desc, state)
if err != nil && err.Error() == "project creation reported as unsuccessful" {
// no detail in the error: verify existing projects to avoid duplicates, then surface context
existing, _ := client.FetchProjects(ctx, "all")
for _, p := range existing {
if p.Name == name { return &p, nil /* already created */ }
}
return fmt.Errorf("linear rejected projectCreate (team=%s, name=%q): check token scopes", client.TeamID, name)
} Prevention
- Validate token write scopes and team membership at startup, not at first create.
- Cross-check TeamID with FetchTeams before mutations.
- Because the sentinel error carries no cause, wrap calls to log the surrounding context (input, team, timestamp).
- After a failed create, search FetchProjects by name to detect partial/duplicate creation before retrying.
- Track Linear API changelog for changes to projectCreate success semantics.
When it happens
Trigger: Execute succeeded and JSON decoded fine, but createResp.ProjectCreate.Success is false — Linear rejected the mutation at the payload level (e.g. validation the API expressed via success flag, permission checks that don't raise GraphQL errors, or a null project node).
Common situations: Token can authenticate but lacks write access to the team; teamIds references a team where project creation is restricted; Linear-side workspace settings block project creation by bots; success flag semantics changed across Linear API versions so the struct reads a stale field.
Related errors
- failed to create project
- batch update unsuccessful, single-issue fallback also…
- failed to fetch issue by identifier
- failed to fetch projects
- failed to fetch teams
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/382ec52a15f1a357.
Report an issue: GitHub.
Appendix: source
Thrown at internal/linear/client.go:1543
req := &GraphQLRequest{
Query: query,
Variables: map[string]interface{}{
"input": input,
},
}
data, err := c.Execute(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to create project: %w", err)
}
var createResp ProjectCreateResponse
if err := json.Unmarshal(data, &createResp); err != nil {
return nil, fmt.Errorf("failed to parse create project response: %w", err)
}
if !createResp.ProjectCreate.Success {
return nil, fmt.Errorf("project creation reported as unsuccessful")
}
return &createResp.ProjectCreate.Project, nil
}
// UpdateProject updates an existing project in Linear.
func (c *Client) UpdateProject(ctx context.Context, projectID string, updates map[string]interface{}) (*Project, error) {
query := `
mutation UpdateProject($id: String!, $input: ProjectUpdateInput!) {
projectUpdate(id: $id, input: $input) {
success
project {
id
name
description
slugId
url
stateView on GitHub (pinned to 71377f2769)