GraphQL mutation design including payload patterns, field-specific errors, input objects, and HTTP semantics. Use when designing or implementing GraphQL mutations.
Expert guidance for designing GraphQL mutations with proper payload patterns, field-specific errors, input objects, and HTTP semantics. Use when designing or implementing GraphQL mutations.
/plugin marketplace add jovermier/cc-stack-marketplace/plugin install cc-graphql@cc-stack-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/errors.mdreferences/inputs.mdreferences/naming.mdreferences/payloads.mdExpert guidance for designing effective GraphQL mutations.
| Pattern | Use When | Structure |
|---|---|---|
| Result payload | All mutations | mutationName(input): MutationNamePayload! |
| Field-specific errors | Validation failures | errors: [FieldError!]! in payload |
| Input objects | Complex arguments | input: MutationNameInput! |
| Noun + Verb naming | State changes | createUser, deletePost, closeCard |
| Idempotent mutations | Safe retries | Design for repeatable calls |
| Optimistic UI | Client-side updates | Return predicted result |
Specify a number or describe your mutation scenario.
| Response | Reference to Read |
|---|---|
| 1, "payload", "return", "response" | payloads.md |
| 2, "input", "argument", "parameter" | inputs.md |
| 3, "error", "validation", "field error" | errors.md |
| 4, "naming", "convention" | naming.md |
| 5, general mutations | Read relevant references |
# Input object for complex arguments
input CreateUserInput {
name: String!
email: String!
password: String!
}
# Payload with result and errors
type CreateUserPayload {
user: User
errors: [UserError!]!
}
# Field-specific error type
type UserError {
field: [String!]! # Path to field: ["email"] or ["user", "emails", 0]
message: String!
}
# Mutation definition
type Mutation {
"""
Creates a new user account
"""
createUser(input: CreateUserInput!): CreateUserPayload!
}
// Good: Mutation with proper payload and field errors
func (r *mutationResolver) CreateUser(ctx context.Context, input CreateUserInput) (*CreateUserPayload, error) {
// Validate
var errs []UserError
if input.Name == "" {
errs = append(errs, UserError{
Field: []string{"name"},
Message: "Name is required",
})
}
if !isValidEmail(input.Email) {
errs = append(errs, UserError{
Field: []string{"email"},
Message: "Invalid email format",
})
}
if len(errs) > 0 {
return &CreateUserPayload{Errors: errs}, nil
}
// Create
user, err := r.db.CreateUser(input)
if err != nil {
if errors.Is(err, db.ErrDuplicate) {
return &CreateUserPayload{
Errors: []UserError{{
Field: []string{"email"},
Message: "Email already exists",
}},
}, nil
}
return nil, fmt.Errorf("failed to create user")
}
return &CreateUserPayload{User: user, Errors: []UserError{}}, nil
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
}
type CreateUserPayload {
user: User
errors: [UserError!]!
}
type Mutation {
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}
type UpdateUserPayload {
user: User
errors: [UserError!]!
}
type Mutation {
deleteUser(id: ID!): DeleteUserPayload!
}
type DeleteUserPayload {
deletedUserId: ID
errors: [UserError!]!
}
type Mutation {
"""
Closes a card (marks as closed, not deleted)
"""
closeCard(id: ID!): CloseCardPayload!
}
type CloseCardPayload {
card: Card
errors: [UserError!]!
}
| Error Type | Response Pattern |
|---|---|
| Validation errors | Return in payload errors field |
| Duplicate unique key | Return in payload errors field |
| Not found | Return in payload errors field |
| Permission denied | Return in payload errors field |
| Internal server error | Return nil, wrap error (don't expose) |
| Concern | Guidance |
|---|---|
| HTTP method | Always POST for mutations |
| Caching | Mutations are never cached |
| Idempotency | Design mutations to be safely repeatable |
| Side effects | Document non-obvious side effects |
| Async operations | Return payload with job ID, query for status |
| Mistake | Severity | Fix |
|---|---|---|
| Returning just boolean | Medium | Use payload with result |
| No field-specific errors | High | Add errors array to payload |
| Too many scalar arguments | Medium | Use input object |
| Verb + noun naming | Low | Use noun + verb (createUser) |
| Using GET for mutations | Critical | Always use POST |
| No validation errors in payload | High | Return validation failures |
| File | Topics |
|---|---|
| payloads.md | Result types, error patterns, response structure |
| inputs.md | Input objects, nested inputs, validation |
| errors.md | Field errors, error types, client handling |
| naming.md | Conventions, verb selection, consistency |
Mutations are well-designed when:
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.