Wei-Shaw/sub2api · error

account platform is required

Error message

account platform is required

What it means

Returned by validateDataAccount (backend/internal/handler/admin/account_data.go:683) when an accounts[] entry has a non-empty name but its platform is empty after TrimSpace. Platform identifies which upstream the account belongs to and is required on every imported account.

Source

Thrown at backend/internal/handler/admin/account_data.go:683

	case "http", "https", "socks5", "socks5h":
	default:
		return fmt.Errorf("proxy protocol is invalid: %s", item.Protocol)
	}
	if item.Status != "" {
		normalizedStatus := normalizeProxyStatus(item.Status)
		if normalizedStatus != service.StatusActive && normalizedStatus != "inactive" {
			return fmt.Errorf("proxy status is invalid: %s", item.Status)
		}
	}
	return nil
}

func validateDataAccount(item DataAccount) error {
	if strings.TrimSpace(item.Name) == "" {
		return errors.New("account name is required")
	}
	if strings.TrimSpace(item.Platform) == "" {
		return errors.New("account platform is required")
	}
	if strings.TrimSpace(item.Type) == "" {
		return errors.New("account type is required")
	}
	if len(item.Credentials) == 0 {
		return errors.New("account credentials is required")
	}
	switch item.Type {
	case service.AccountTypeOAuth, service.AccountTypeSetupToken, service.AccountTypeAPIKey, service.AccountTypeUpstream:
	default:
		return fmt.Errorf("account type is invalid: %s", item.Type)
	}
	if item.RateMultiplier != nil && *item.RateMultiplier < 0 {
		return errors.New("rate_multiplier must be >= 0")
	}
	if item.Concurrency < 0 {
		return errors.New("concurrency must be >= 0")
	}

View on GitHub (pinned to 073e92d171)

Solutions

  1. Set platform to the expected platform identifier (e.g. "openai") on the entry.
  2. Check the export/import schema docs for the exact field name and allowed values.
  3. Map renamed fields when converting from other formats.

Example fix

// before
{ "name": "main", "type": "oauth", "credentials": { ... } }

// after
{ "name": "main", "platform": "openai", "type": "oauth", "credentials": { ... } }
Defensive patterns

Strategy: validation

Validate before calling

function hasAccountPlatform(entry: Record<string, unknown>): boolean {
  return typeof entry.platform === 'string' && entry.platform.trim() !== ''
}

Type guard

function hasRequiredAccountStrings(e: unknown, keys: string[]): e is Record<string, string> {
  if (typeof e !== 'object' || e === null) return false
  const o = e as Record<string, unknown>
  return keys.every((k) => typeof o[k] === 'string' && (o[k] as string).trim() !== '')
}

Prevention

When it happens

Trigger: An account object with name and type but platform missing/blank; a key renamed (e.g. 'provider') so platform is never set.

Common situations: Schema drift between export tools; hand-written payloads guessing field names; whitespace platform values from forms.

Related errors


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/4137520f71ac0c7a. Report an issue: GitHub.