{"record":{"id":"5868d555ee320076","repo":"router-for-me/CLIProxyAPI","slug":"auth-index-is-required","errorCode":null,"errorMessage":"auth_index is required","messagePattern":"auth_index is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/auth_callbacks.go","lineNumber":76,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"decode host auth list request: %w\", errUnmarshal)\n\t\t}\n\t}\n\tentries, errList := h.listAuthFiles()\n\tif errList != nil {\n\t\treturn nil, errList\n\t}\n\treturn marshalRPCResult(rpcHostAuthListResponse{Files: entries})\n}\n\nfunc (h *Host) callHostAuthGet(ctx context.Context, request []byte) ([]byte, error) {\n\t_ = ctx\n\tvar req rpcHostAuthGetRequest\n\tif errUnmarshal := json.Unmarshal(request, &req); errUnmarshal != nil {\n\t\treturn nil, fmt.Errorf(\"decode host auth get request: %w\", errUnmarshal)\n\t}\n\tauthIndex := strings.TrimSpace(req.AuthIndex)\n\tif authIndex == \"\" {\n\t\treturn nil, fmt.Errorf(\"auth_index is required\")\n\t}\n\tauth, rawJSON, errGet := h.authPhysicalJSONByIndex(authIndex)\n\tif errGet != nil {\n\t\treturn nil, errGet\n\t}\n\tname := strings.TrimSpace(auth.FileName)\n\tif name == \"\" {\n\t\tname = strings.TrimSpace(auth.ID)\n\t}\n\tpath := strings.TrimSpace(authAttribute(auth, \"path\"))\n\treturn marshalRPCResult(rpcHostAuthGetResponse{\n\t\tAuthIndex: authIndex,\n\t\tName:      name,\n\t\tPath:      path,\n\t\tJSON:      json.RawMessage(rawJSON),\n\t})\n}\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/auth_callbacks.go#L58-L94","documentation":"The host's auth.get callback requires a non-empty auth_index; the request decoded but auth_index was empty or only whitespace, so the callback refuses to look up anything.","triggerScenarios":"Plugin calls host auth get with auth_index omitted, empty string, or whitespace — e.g. it enumerated auth files, got no entries, and passed through an empty index unchecked.","commonSituations":"Plugin logic that derives auth_index from a previous list call returning nothing; default/zero-value struct serialized without omitzero; plugin assumes an implicit 'first' auth which the protocol does not have.","solutions":["In the plugin, list auth files first (auth.list) and pass a concrete AuthIndex from the result","Fail fast in the plugin when the derived auth_index is empty instead of calling the host","Check that the plugin's request struct sets the auth_index json tag correctly"],"exampleFix":"// before\nreq := HostAuthGetRequest{} // AuthIndex empty\nresp, err := host.AuthGet(ctx, req)\n\n// after\nif strings.TrimSpace(idx) == \"\" {\n    return errors.New(\"no auth_index available\")\n}\nresp, err := host.AuthGet(ctx, HostAuthGetRequest{AuthIndex: idx})","handlingStrategy":"validation","validationCode":"idx := strings.TrimSpace(entry.AuthIndex)\nif idx == \"\" {\n    return errors.New(\"no auth_index from list result; nothing to get\")\n}\nresp, err := hostClient.AuthGet(ctx, HostAuthGetRequest{AuthIndex: idx})","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat an empty auth list as 'stop', never 'use empty index'","Mark required RPC fields in plugin structs and check them before send","Log the originating RPC payload when validation fails at the host"],"tags":["plugin","rpc","validation","auth"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}