router-for-me/CLIProxyAPI · error
auth file name must end with .json
Error message
auth file name must end with .json
What it means
Thrown by validateHostAuthSaveRequest when the (safe) file name does not end with .json (checked case-insensitively). Auth files must be JSON files so the loader and watchers can parse them; other extensions are rejected at save time.
Source
Thrown at internal/pluginhost/auth_callbacks.go:268
return nil, nil, fmt.Errorf("failed to read auth file: %w", errRead)
}
if len(bytesTrimSpace(data)) == 0 {
return nil, nil, fmt.Errorf("auth file is empty for auth_index %s", authIndex)
}
var metadata map[string]any
if errUnmarshal := json.Unmarshal(data, &metadata); errUnmarshal != nil {
return nil, nil, fmt.Errorf("invalid auth file for auth_index %s: %w", authIndex, errUnmarshal)
}
return auth, data, nil
}
func validateHostAuthSaveRequest(req pluginapi.HostAuthSaveRequest) (string, []byte, error) {
name := strings.TrimSpace(req.Name)
if isUnsafeAuthFileName(name) {
return "", nil, fmt.Errorf("invalid auth file name")
}
if !strings.HasSuffix(strings.ToLower(name), ".json") {
return "", nil, fmt.Errorf("auth file name must end with .json")
}
rawJSON := bytesTrimSpace(req.JSON)
if len(rawJSON) == 0 {
return "", nil, fmt.Errorf("json is required")
}
var metadata map[string]any
if errUnmarshal := json.Unmarshal(rawJSON, &metadata); errUnmarshal != nil {
return "", nil, fmt.Errorf("invalid auth json: %w", errUnmarshal)
}
return filepath.Base(name), rawJSON, nil
}
func (h *Host) saveAuthFile(ctx context.Context, name string, data []byte) (string, error) {
authDir := h.resolvedAuthDir()
if authDir == "" {
return "", fmt.Errorf("auth directory is unavailable")
}
dst := filepath.Join(authDir, filepath.Base(name))View on GitHub (pinned to 78f0c4079e)
Solutions
- Append .json to the name before calling save if missing
- Derive names from an existing listing (listAuthFiles returns *.json names) to match the convention
Example fix
// before
name := "openai-credentials"
// after
if !strings.HasSuffix(strings.ToLower(name), ".json") {
name += ".json"
} Defensive patterns
Strategy: validation
Validate before calling
if !strings.HasSuffix(strings.ToLower(name), ".json") {
name += ".json"
} Prevention
- Centralize auth file naming in one helper that enforces the .json suffix
- Copy names from listAuthFiles output to stay consistent
When it happens
Trigger: Plugin submits name 'credentials', 'auth.txt', or 'auth.JSON5' — anything whose lowercase form lacks the .json suffix.
Common situations: Plugin derives the extension from a provider config value; version bump of a plugin changed its naming convention; copy-paste of a non-Go filename convention.
Related errors
- invalid auth file name
- json is required
- invalid auth json: %w
- auth path is empty
- invalid auth weight: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/24ab2daab143c2e5.
Report an issue: GitHub.