hcengineering/platform · error

Missing required fields: type, plan

Error message

Missing required fields: type, plan

What it means

The subscribe endpoint validates that the request body (a SubscribeRequest) contains both 'type' ('tier' or 'support') and 'plan' before calling the payment provider. If either is undefined it returns HTTP 400 without contacting the provider. This is a plain request-shape validation failure, so the provider is never invoked.

Source

Thrown at services/payment/pod-payment/src/server.ts:227

          const loginInfo = req.loginInfo as WorkspaceLoginInfo

          if (accountUuid === undefined) {
            res.status(401).json({ error: 'Missing account in token' })
            return
          }

          if (workspaceUuid === undefined) {
            res.status(401).json({ error: 'Missing workspace in token' })
            return
          }

          if (loginInfo?.workspaceUrl === undefined) {
            res.status(401).json({ error: 'Missing workspace url in login info' })
            return
          }

          if (request.type === undefined || request.plan === undefined) {
            res.status(400).json({ error: 'Missing required fields: type, plan' })
            return
          }

          let createSubResponse: CheckoutResponse

          try {
            createSubResponse = await provider.createSubscription(
              ctx,
              request,
              workspaceUuid,
              loginInfo.workspaceUrl,
              accountUuid
            )
          } catch (err) {
            ctx.error('Failed to create subscription at provider', { err })
            res.status(500).json({ error: 'Failed to create subscription at provider' })
            return
          }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Include both required fields in the request body: { "type": "tier"|"support", "plan": "<plan-name>" }.
  2. Verify the request Content-Type is application/json so Express parses the body (and that a body parser middleware is enabled).
  3. Check client code for renamed fields after a client-library upgrade and align with SubscribeRequest.
  4. Add client-side form validation ensuring a plan is chosen before submitting.

Example fix

// before
await fetch(url, { method: 'POST', body: JSON.stringify({ plan: 'epic' }) })

// after
await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'tier', plan: 'epic' }) })
Defensive patterns

Strategy: validation

Validate before calling

function isValidSubscribeRequest(body: unknown): body is SubscribeRequest {
  const b = body as SubscribeRequest
  return (b.type === 'tier' || b.type === 'support') && typeof b.plan === 'string' && b.plan.length > 0
}
// call before POST: if (!isValidSubscribeRequest(payload)) return

Type guard

function isSubscribeRequest(v: unknown): v is SubscribeRequest {
  const b = v as Partial<SubscribeRequest>
  return (b.type === 'tier' || b.type === 'support') && typeof b.plan === 'string'
}

Try / catch

const res = await fetch(subscribeUrl, opts)
if (res.status === 400) {
  const body = await res.json()
  if (body.error === 'Missing required fields: type, plan') {
    // fix payload shape and resubmit; this is not retryable as-is
  }
}

Prevention

When it happens

Trigger: POST /api/v1/subscriptions/:workspace/subscribe with a JSON body missing 'type' and/or 'plan', sending them under wrong names (e.g. 'planId', 'subscriptionType'), sending an empty body, or a client that fails to JSON-serialize the body so req.body only carries partial fields.

Common situations: Typos or renamed fields after an API client upgrade; curl/Postman calls with forgotten body; frontend form submitted before plan selection; Content-Type not application/json so body fields end up undefined.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/2870f8789c43bbb0. Report an issue: GitHub.