vitessio/vitess · error
a POST request must specify action
Error message
a POST request must specify action
What it means
Within the keyspaces POST handler, after confirming a keyspace is present in the URL, the handler reads the 'action' form value; POSTs are strictly action-dispatch endpoints, so an empty action yields this error before ApplyKeyspaceAction is invoked.
Source
Thrown at go/vt/vtctld/api.go:221
// Get the keyspace record.
k, err := ts.GetKeyspace(ctx, keyspace)
if err != nil {
return nil, err
}
// Pass the embedded proto directly or jsonpb will panic.
return k.Keyspace, err
// Perform an action on a keyspace.
case "POST":
if keyspace == "" {
return nil, errors.New("a POST request needs a keyspace in the URL")
}
if err := r.ParseForm(); err != nil {
return nil, err
}
action := r.FormValue("action")
if action == "" {
return nil, errors.New("a POST request must specify action")
}
return actions.ApplyKeyspaceAction(ctx, action, keyspace), nil
default:
return nil, fmt.Errorf("unsupported HTTP method: %v", r.Method)
}
})
handleCollection("keyspace", func(r *http.Request) (any, error) {
// Valid requests: api/keyspace/my_ks/tablets (all shards)
// Valid requests: api/keyspace/my_ks/tablets/-80 (specific shard)
itemPath := getItemPath(r.URL.Path)
parts := strings.SplitN(itemPath, "/", 3)
malformedRequestError := fmt.Errorf("invalid keyspace path: %q expected path: /keyspace/<keyspace>/tablets or /keyspace/<keyspace>/tablets/<shard>", itemPath)
if len(parts) < 2 {
return nil, malformedRequestError
}
if parts[1] != "tablets" {View on GitHub (pinned to 01a25a7d17)
Solutions
- Add action=<name> as a form field to the POST body (application/x-www-form-urlencoded).
- Use a valid keyspace action name as accepted by ApplyKeyspaceAction (e.g. 'Refresh').
- Ensure the Content-Type header is form-encoded, not JSON.
Example fix
// before
curl -X POST http://localhost:15000/api/keyspaces/commerce -H 'Content-Type: application/json' -d '{"action":"Refresh"}'
// after
curl -X POST http://localhost:15000/api/keyspaces/commerce -d 'action=Refresh' Defensive patterns
Strategy: validation
Validate before calling
if action == "" {
return fmt.Errorf("keyspace POST requires a non-empty 'action' form field")
}
form := url.Values{"action": {action}} Try / catch
resp, err := http.PostForm(u, form)
if err != nil || strings.Contains(status, "must specify action") {
// fix: always send action=<name> as x-www-form-urlencoded
} Prevention
- Always send 'action' as a form field, never JSON, for these endpoints.
- Validate the action string against ApplyKeyspaceAction's accepted set.
When it happens
Trigger: POST /api/keyspaces/<keyspace> with a body missing the 'action' form field, or sending an empty action= value; also sending JSON bodies the handler cannot read as form values (ParseForm sees nothing).
Common situations: Clients sending application/json instead of application/x-www-form-urlencoded so FormValue('action') is empty; typos in the field name (e.g. 'operation'); forgetting the body entirely.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- a POST request needs a keyspace in the URL
- must specify action
- cells can only be listed, not retrieved
- keyspace is required
- no local cells have been created yet
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/996ea65279d3efd3.
Report an issue: GitHub.