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).

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)

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.