router-for-me/CLIProxyAPI · error

auth file not found

Error message

auth file not found

What it means

Thrown when the plugin host cannot JSON-decode the RPC payload that a plugin sent for the host.model.execute_stream callback. The request bytes must unmarshal into rpcHostModelExecutionRequest; any syntax error, wrong field type, or truncated payload fails here. It always wraps the underlying encoding/json error with %w.

Source

Thrown at internal/api/handlers/management/auth_files.go:32

	"github.com/gin-gonic/gin"
	"github.com/router-for-me/CLIProxyAPI/v7/internal/auth/codex"
	"github.com/router-for-me/CLIProxyAPI/v7/internal/config"
	"github.com/router-for-me/CLIProxyAPI/v7/internal/credentialweight"
	"github.com/router-for-me/CLIProxyAPI/v7/internal/registry"
	coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
	log "github.com/sirupsen/logrus"
	"github.com/tidwall/gjson"
)

var lastRefreshKeys = []string{"last_refresh", "lastRefresh", "last_refreshed_at", "lastRefreshedAt"}

var (
	callbackForwardersMu  sync.Mutex
	callbackForwarders    = make(map[int]*callbackForwarder)
	authFileEntryMu       sync.Mutex
	errAuthFileMustBeJSON = errors.New("auth file must be .json")
	errAuthFileNotFound   = errors.New("auth file not found")
	errPluginVirtualAuth  = errors.New("plugin virtual auth cannot be modified directly; edit or delete the source auth file")
	newCodexOAuthService  = func(cfg *config.Config) codexOAuthService { return codex.NewCodexAuth(cfg) }
)

func extractLastRefreshTimestamp(meta map[string]any) (time.Time, bool) {
	if len(meta) == 0 {
		return time.Time{}, false
	}
	for _, key := range lastRefreshKeys {
		if val, ok := meta[key]; ok {
			if ts, ok1 := parseLastRefreshValue(val); ok1 {
				return ts, true
			}
		}
	}
	return time.Time{}, false
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Rebuild the plugin against the same SDK/pluginapi version the host binary uses (go.mod module github.com/router-for-me/CLIProxyAPI/v7).
  2. Log the raw request bytes at the RPC boundary to identify which field fails to unmarshal.
  3. Validate in the plugin that the request is serialized with json.Marshal of the generated HostModelExecutionRequest struct, not hand-built JSON.
  4. Check the C buffer handling (length vs NUL termination) if the plugin is not written in Go.

Example fix

// plugin side: marshal the typed struct, never hand-build the payload
req := pluginapi.HostModelExecutionRequest{Model: "gpt-4o", Stream: true, /* ... */}
raw, err := json.Marshal(req)
if err != nil {
    return err
}
resp, err := host.Call(ctx, "host.model.execute_stream", raw)
Defensive patterns

Strategy: try-catch

Validate before calling

// plugin side: marshal the typed struct before sending
raw, err := json.Marshal(req)
if err != nil {
    return fmt.Errorf("serialize request: %w", err)
}

Try / catch

_, err := host.Call(ctx, "host.model.execute_stream", raw)
if err != nil {
    var syntaxErr *json.SyntaxError
    if errors.As(err, &syntaxErr) {
        // request payload malformed on our side: fix serialization, do not retry
        return fmt.Errorf("plugin request schema bug: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A plugin calls host.model.execute_stream with a malformed JSON body: truncated buffers from the C ABI boundary, string values where numbers are expected, or a request struct serialized by a plugin built against an older/newer rpcHostModelExecutionRequest schema.

Common situations: Plugin compiled from a different SDK version whose request struct differs from the host's; bugs in the plugin's RPC serialization; memory corruption in the C bridge producing garbage bytes; manual JSON hand-crafted for testing.

Related errors


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