diff --git a/frontend/src/pages/inbounds/form/InboundFormModal.tsx b/frontend/src/pages/inbounds/form/InboundFormModal.tsx index 6cd021292..2389e1385 100644 --- a/frontend/src/pages/inbounds/form/InboundFormModal.tsx +++ b/frontend/src/pages/inbounds/form/InboundFormModal.tsx @@ -176,6 +176,10 @@ export default function InboundFormModal({ const selectableNodes = (availableNodes || []).filter((n) => n.enable); const protocol = (Form.useWatch('protocol', form) ?? '') as string; const isNodeEligible = NODE_ELIGIBLE_PROTOCOLS.has(protocol); + // The `node` share-address strategy only means something when the inbound can + // actually live on a node — otherwise the node address it would resolve to is + // always empty. Offer it only then; `listen`/`custom` work for local inbounds. + const nodeShareOptionAvailable = selectableNodes.length > 0 && isNodeEligible; const sniffingEnabled = Form.useWatch(['sniffing', 'enabled'], form) ?? false; const vlessEncryption = Form.useWatch(['settings', 'encryption'], form) ?? ''; const ssMethod = Form.useWatch(['settings', 'method'], form); @@ -370,6 +374,18 @@ export default function InboundFormModal({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, wPort, wNodeId, protocol, network, mixedUdpOn, wSsNetwork, wTunnelNetwork]); + // Keep the strategy value inside the visible option set: when `node` isn't + // offered (no node, or a protocol that can't deploy to one) fall back to + // `listen`, which yields the same link for a local inbound. Mirrors how the + // protocol reset drops a nodeId that no longer applies. + useEffect(() => { + if (!open) return; + if (!nodeShareOptionAvailable && shareAddrStrategy === 'node') { + form.setFieldValue('shareAddrStrategy', 'listen'); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open, nodeShareOptionAvailable, shareAddrStrategy]); + // Why: protocol picker reset cascades through the form — clearing the // settings DU branch and dropping a nodeId that no longer applies. The // legacy modal did this imperatively in onProtocolChange; here we hook @@ -532,10 +548,12 @@ export default function InboundFormModal({ extra={t('pages.inbounds.form.shareAddrStrategyHelp')} >