Wei-Shaw/sub2api · error

accounts is required

Error message

accounts is required

What it means

Returned by validateDataHeader (backend/internal/handler/admin/account_data.go:649) when the top-level "accounts" key is missing from the data payload (payload.Accounts == nil). Like proxies, an explicitly empty array [] passes, but an absent key fails — the handler requires both containers to be present so accidental omission cannot silently import nothing.

Source

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

	case "0", "false", "no", "off":
		return false, nil
	default:
		return true, fmt.Errorf("invalid include_proxies value: %s", raw)
	}
}

func validateDataHeader(payload DataPayload) error {
	if payload.Type != "" && payload.Type != dataType && payload.Type != legacyDataType {
		return fmt.Errorf("unsupported data type: %s", payload.Type)
	}
	if payload.Version != 0 && payload.Version != dataVersion {
		return fmt.Errorf("unsupported data version: %d", payload.Version)
	}
	if payload.Proxies == nil {
		return errors.New("proxies is required")
	}
	if payload.Accounts == nil {
		return errors.New("accounts is required")
	}
	return nil
}

func validateDataProxy(item DataProxy) error {
	if strings.TrimSpace(item.Protocol) == "" {
		return errors.New("proxy protocol is required")
	}
	if strings.TrimSpace(item.Host) == "" {
		return errors.New("proxy host is required")
	}
	if item.Port <= 0 || item.Port > 65535 {
		return errors.New("proxy port is invalid")
	}
	switch item.Protocol {
	case "http", "https", "socks5", "socks5h":
	default:
		return fmt.Errorf("proxy protocol is invalid: %s", item.Protocol)

View on GitHub (pinned to 073e92d171)

Solutions

  1. Include "accounts": [] (or your accounts) in the payload's top level.
  2. Fix the generating code to always emit the accounts array even when empty.
  3. Validate presence of both keys before upload.

Example fix

// before
{ "type": "data", "version": 1, "proxies": [ ... ] }

// after
{ "type": "data", "version": 1, "proxies": [ ... ], "accounts": [] }
Defensive patterns

Strategy: validation

Validate before calling

function hasAccountsKey(payload: unknown): boolean {
  return typeof payload === 'object' && payload !== null && 'accounts' in payload && Array.isArray((payload as any).accounts)
}

Type guard

function isShapedDataPayload(p: unknown): p is { proxies?: unknown[]; accounts: unknown[] } {
  return typeof p === 'object' && p !== null && Array.isArray((p as { accounts?: unknown }).accounts)
}

Prevention

When it happens

Trigger: POSTing a payload with only "proxies" and no "accounts" key; a serializer configured to skip empty account lists; merging payload fragments and dropping the accounts branch.

Common situations: Proxy-only import attempted with a hand-trimmed JSON; Go/Python serializers with omitempty/skip-empty behavior; editing an export in a JSON editor and deleting the accounts key.

Related errors


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