{"record":{"id":"03c90ca537c58805","repo":"MHSanaei/3x-ui","slug":"remote-addclient-resolve-tag-q-w","errorCode":null,"errorMessage":"remote AddClient: resolve tag %q: %w","messagePattern":"remote AddClient: resolve tag %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/web/runtime/remote.go","lineNumber":545,"sourceCode":"\n// wireFingerprint hashes a wire payload so an unchanged inbound is cheap to detect.\nfunc wireFingerprint(v url.Values) string {\n\tsum := sha256.Sum256([]byte(v.Encode()))\n\treturn hex.EncodeToString(sum[:])\n}\n\nfunc (r *Remote) AddUser(ctx context.Context, ib *model.Inbound, _ map[string]any) error {\n\treturn r.UpdateInbound(ctx, ib, ib)\n}\n\nfunc (r *Remote) RemoveUser(ctx context.Context, ib *model.Inbound, _ string) error {\n\treturn r.UpdateInbound(ctx, ib, ib)\n}\n\nfunc (r *Remote) AddClient(ctx context.Context, ib *model.Inbound, client model.Client) error {\n\tid, err := r.resolveRemoteID(ctx, ib.Tag)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"remote AddClient: resolve tag %q: %w\", ib.Tag, err)\n\t}\n\tpayload := map[string]any{\n\t\t\"client\":     client,\n\t\t\"inboundIds\": []int{id},\n\t}\n\tif _, err := r.do(ctx, http.MethodPost, \"panel/api/clients/add\", payload); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (r *Remote) DeleteUser(ctx context.Context, ib *model.Inbound, email string) error {\n\tif email == \"\" {\n\t\treturn nil\n\t}\n\tid, err := r.resolveRemoteID(ctx, ib.Tag)\n\tif err != nil {\n\t\t// Can't confirm the delete reached the node — surface it so the caller","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/runtime/remote.go#L527-L563","documentation":"Wraps the resolveRemoteID failure inside Remote.AddClient: the central panel tried to add a client to an inbound on a node, but could not map the inbound's tag to the node-local inbound ID first. The inner error is either the refresh failure (network/decode, errors 100-109) or the tag-not-found error (107).","triggerScenarios":"Adding a client to a node-assigned inbound whose tag does not exist on the node, or while the node is unreachable so the ID cache cannot be refreshed. The payload (client + inboundIds) is never sent.","commonSituations":"Client add raced a node-side inbound deletion; node offline mid-operation; tag drifted after out-of-band node edits.","solutions":["Resolve node reachability first if the inner error is a transport/decode failure (see the wrapped message).","If the inner error is 'not found on node', push/re-save the inbound on the master so the node recreates it, then retry the client add.","Avoid direct node-side inbound edits that break tag parity with the central panel.","Run a reconcile for the node to converge inbound state before retrying per-client writes."],"exampleFix":"// before: err: remote AddClient: resolve tag \"n2-vmess-in\": remote inbound with tag \"n2-vmess-in\" not found on node edge-2\n\n// after: re-save the inbound on the central panel (re-pushes it to the node), then retry the client add","handlingStrategy":"retry","validationCode":"if _, err := remote.ResolveTag(ctx, ib.Tag); err != nil {\n    return fmt.Errorf(\"inbound not present on node; push it before adding clients: %w\", err)\n}","typeGuard":"func isResolveFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"resolve tag\")\n}","tryCatchPattern":"if err := remote.AddClient(ctx, ib, client); err != nil {\n    if isResolveFailure(err) {\n        if perr := pushInbound(ctx, ib); perr != nil { return errors.Join(err, perr) }\n        return remote.AddClient(ctx, ib, client) // one converged retry\n    }\n    return err\n}","preventionTips":["Always create/push the inbound on the node before adding clients to it.","Check node health before bulk client imports on node-assigned inbounds.","Never rename inbounds directly on nodes."],"tags":["node-sync","client-management","tag-mismatch","remote"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}