fatedier/frp · error
unsupported value source type: %s
Error message
unsupported value source type: %s
What it means
ValueSource.Resolve() hits its default switch branch when Type is neither "file" nor "exec". In practice this branch is nearly unreachable because Resolve() calls Validate() first, which rejects the same condition with a more descriptive message (error 260). Seeing this exact message usually means Validate() was bypassed or the struct was mutated between validation and resolution.
Source
Thrown at pkg/config/v1/value_source.go:85
return v.Exec.Validate()
default:
return fmt.Errorf("unsupported value source type: %s (only 'file' and 'exec' are supported)", v.Type)
}
}
// Resolve resolves the value from the configured source.
func (v *ValueSource) Resolve(ctx context.Context) (string, error) {
if err := v.Validate(); err != nil {
return "", err
}
switch v.Type {
case "file":
return v.File.Resolve(ctx)
case "exec":
return v.Exec.Resolve(ctx)
default:
return "", fmt.Errorf("unsupported value source type: %s", v.Type)
}
}
// Validate validates the FileSource configuration.
func (f *FileSource) Validate() error {
if f == nil {
return errors.New("fileSource cannot be nil")
}
if f.Path == "" {
return errors.New("file path cannot be empty")
}
return nil
}
// Resolve reads and returns the content from the specified file.
func (f *FileSource) Resolve(_ context.Context) (string, error) {
if err := f.Validate(); err != nil {View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Fix the Type to "file" or "exec" as with error 260 — this is the same root cause.
- If you mutate ValueSource fields, re-run Validate() after mutation and before Resolve().
- Avoid sharing a ValueSource across goroutines with writes; construct a fresh one per resolution.
Example fix
// before
vs := &ValueSource{Type: "vault"}
val, err := vs.Resolve(ctx)
// after
vs := &ValueSource{Type: "exec", Exec: &ExecSource{Command: "vault", Args: []string{"kv", "get", "-field=tok", "frp"}}}
if err := vs.Validate(); err != nil { return err }
val, err := vs.Resolve(ctx) Defensive patterns
Strategy: validation
Validate before calling
if err := vs.Validate(); err != nil {
return "", fmt.Errorf("value source invalid: %w", err)
} Prevention
- Always call Validate() before Resolve() and surface its richer message.
- Treat ValueSource as immutable after construction; do not mutate Type concurrently.
When it happens
Trigger: Calling ValueSource.Resolve(ctx) with an unsupported Type while somehow skipping the upfront Validate() error — e.g. code that ignores the Validate() error inside Resolve, or a ValueSource mutated concurrently after validation.
Common situations: A concurrent goroutine rewrites v.Type between the Validate() call at the top of Resolve and the switch; custom code copies the struct and changes Type without revalidating.
Related errors
- unsupported value source type: %s (only 'file' and 'exec' ar
- file configuration is required when type is 'file'
- exec configuration is required when type is 'exec'
- file path cannot be empty
- exec command cannot be empty
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/3cb57a69cadb6b9a.
Report an issue: GitHub.