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

  1. Add action=<name> as a form field to the POST body (application/x-www-form-urlencoded).
  2. Use a valid keyspace action name as accepted by ApplyKeyspaceAction (e.g. 'Refresh').
  3. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/996ea65279d3efd3. Report an issue: GitHub.