router-for-me/CLIProxyAPI · error

invalid name

Error message

invalid name

What it means

deleteAuthFileByName first trims the requested name and runs isUnsafeAuthFileName (auth_files.go:573), which rejects empty names, any name containing `/` or `\\`, and Windows volume names (`C:`). A rejection yields HTTP 400 `invalid name` — this is the path-traversal/empty-name guard for the delete endpoint, not a signal about the file itself.

Source

Thrown at internal/api/handlers/management/auth_files_crud.go:345

	out := make([]string, 0, len(names))
	for _, name := range names {
		name = strings.TrimSpace(name)
		if name == "" {
			continue
		}
		if _, ok := seen[name]; ok {
			continue
		}
		seen[name] = struct{}{}
		out = append(out, name)
	}
	return out
}

func (h *Handler) deleteAuthFileByName(ctx context.Context, name string) (string, int, error) {
	name = strings.TrimSpace(name)
	if isUnsafeAuthFileName(name) {
		return "", http.StatusBadRequest, fmt.Errorf("invalid name")
	}

	targetPath := filepath.Join(h.cfg.AuthDir, filepath.Base(name))
	targetID := ""
	if targetAuth := h.findAuthForDelete(name); targetAuth != nil {
		if !isPluginVirtualSourceDelete(name, targetAuth) {
			return filepath.Base(name), http.StatusConflict, errPluginVirtualAuth
		}
		targetID = strings.TrimSpace(targetAuth.ID)
		if path := strings.TrimSpace(authAttribute(targetAuth, "path")); path != "" {
			targetPath = path
		}
	}
	if !filepath.IsAbs(targetPath) {
		if abs, errAbs := filepath.Abs(targetPath); errAbs == nil {
			targetPath = abs
		}
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Send only the base filename: strip directories before calling delete (name = filepath.Base(name)).
  2. Reject empty/whitespace names client-side before issuing the request.
  3. Never send absolute paths or drive letters; the handler always joins with the configured authDir.

Example fix

// before
name := "/etc/cli-proxy-api/auths/my.json"
// after
name := filepath.Base("/etc/cli-proxy-api/auths/my.json") // "my.json"
Defensive patterns

Strategy: validation

Validate before calling

func safeAuthFileName(name string) bool {
    n := strings.TrimSpace(name)
    return n != "" && !strings.ContainsAny(n, "/\\") && filepath.VolumeName(n) == ""
}

Type guard

func isInvalidNameError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "invalid name")
}

Prevention

When it happens

Trigger: DELETE with name like `../auths/secret.json`, `dir/file.json`, `C:\\auths\\x.json`, empty string after trimming, or a path-style identifier from another API surface; clients passing a full path where only a basename is allowed.

Common situations: Automation using absolute paths from the host filesystem; accidental inclusion of leading `/`; names built by joining directories; Windows clients sending backslash paths.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/f14b5fc6bb677e00. Report an issue: GitHub.