fatedier/frp · error

ErrInvalidArgument

ErrInvalidArgument

Error message

invalid argument

What it means

configmgmt.ErrInvalidArgument is the frpc config-manager sentinel for caller mistakes. Manager methods in client/config_manager.go wrap it (via %w) around concrete causes: empty config file path, empty request body, missing proxy/visitor name, type field missing in a submitted config, URL name not matching body name, or failed config validation. The frpc admin HTTP layer maps it to 400 Bad Request (client/http/controller.go:60).

Solutions

  1. Match on errors.Is(err, configmgmt.ErrInvalidArgument) and read the suffix after the colon — it names the exact bad field
  2. Ensure POST/PUT bodies include both name and type and that the URL name equals the body name
  3. Pass a config file path (-c) when using file-based operations like ReadConfigFile/ReloadFromFile
  4. Fix the validation error named in the message, then re-run validation locally before resubmitting

Example fix

// before
curl -X POST localhost:7400/api/proxy -d '{"type":"tcp"}' // 400 invalid argument: proxy name is required

// after
curl -X POST localhost:7400/api/proxy -d '{"type":"tcp","name":"ssh","remotePort":22}'
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling manager/admin APIs
func validProxyPayload(p v1.TypedProxyConfig) error {
    b := p.GetBaseConfig()
    if b == nil || b.Name == "" { return fmt.Errorf("name is required") }
    if p.Type() == "" { return fmt.Errorf("type is required") }
    return nil
}

Try / catch

err := mgr.CreateProxy(ctx, cfg)
if err != nil {
    if errors.Is(err, configmgmt.ErrInvalidArgument) {
        return http.Error(w, err.Error(), http.StatusBadRequest) // message names the bad field
    }
    return err
}

Prevention

When it happens

Trigger: POST/PUT to frpc admin endpoints /api/config or /api/proxy|visitor with an empty body, a config lacking 'name' or 'type', a URL name that differs from the body name, or a payload that fails CompleteProxyConfigurers validation. ReloadFromFile/ReadConfigFile also wrap it when frpc was started with no config file path (-c flag / config path empty).

Common situations: Automating frpc config via the admin API and forgetting required fields; renaming a proxy in the body but not the URL; running frpc purely from flags so no config file exists; whitespace/JSON shape mistakes that fail strict validation.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/1e1a4ca01c070f32. Report an issue: GitHub.

Appendix: source

Thrown at client/configmgmt/types.go:12

package configmgmt

import (
	"errors"
	"time"

	"github.com/fatedier/frp/client/proxy"
	v1 "github.com/fatedier/frp/pkg/config/v1"
)

var (
	ErrInvalidArgument = errors.New("invalid argument")
	ErrNotFound        = errors.New("not found")
	ErrConflict        = errors.New("conflict")
	ErrStoreDisabled   = errors.New("store disabled")
	ErrApplyConfig     = errors.New("apply config failed")
)

type ConfigManager interface {
	ReloadFromFile(strict bool) error

	ReadConfigFile() (string, error)
	WriteConfigFile(content []byte) error

	GetProxyStatus() []*proxy.WorkingStatus
	IsStoreProxyEnabled(name string) bool
	StoreEnabled() bool

	GetProxyConfig(name string) (v1.ProxyConfigurer, bool)
	GetVisitorConfig(name string) (v1.VisitorConfigurer, bool)

View on GitHub (pinned to 6c8a8d0a97)