fix: disable balancer fallbackTag for random / roundRobin strategies

Xray-core's RandomStrategy and RoundRobinStrategy register a pending
dependency on the Observatory feature whenever fallbackTag is non-empty.
Since the panel only provisions observatory for leastPing / leastLoad
balancers, picking roundRobin with a fallbackTag caused xray to fail
boot with "not all dependencies are resolved". Disable the fallback
field for the two strategies that cannot resolve it, and strip
fallbackTag from the wire balancer as a defensive backstop for users
who edit the JSON template directly.
This commit is contained in:
MHSanaei
2026-05-15 11:24:50 +02:00
parent 79a9be7b22
commit 5cf8a08540
2 changed files with 15 additions and 3 deletions

View File

@@ -61,6 +61,16 @@ const isValid = computed(
() => !tagEmpty.value && !duplicateTag.value && !emptySelector.value,
);
const fallbackSupported = computed(
() => form.strategy === 'leastPing' || form.strategy === 'leastLoad',
);
watch(() => form.strategy, (next) => {
if (next !== 'leastPing' && next !== 'leastLoad') {
form.fallbackTag = '';
}
});
const tagValidateStatus = computed(() => {
if (tagEmpty.value) return 'error';
if (duplicateTag.value) return 'warning';
@@ -111,8 +121,9 @@ const okText = computed(() =>
</a-select>
</a-form-item>
<a-form-item label="Fallback">
<a-select v-model:value="form.fallbackTag" allow-clear>
<a-form-item label="Fallback"
:help="fallbackSupported ? '' : 'Available only with Least ping / Least load'">
<a-select v-model:value="form.fallbackTag" allow-clear :disabled="!fallbackSupported">
<a-select-option v-for="tag in ['', ...outboundTags]" :key="tag || '__empty'" :value="tag">
{{ tag || `(${t('none')})` }}
</a-select-option>

View File

@@ -145,10 +145,11 @@ function syncObservatories() {
}
function buildWireBalancer(form) {
const supportsFallback = form.strategy === 'leastPing' || form.strategy === 'leastLoad';
const out = {
tag: form.tag,
selector: [...form.selector],
fallbackTag: form.fallbackTag,
fallbackTag: supportsFallback ? form.fallbackTag : '',
};
if (form.strategy && form.strategy !== 'random') {
out.strategy = { type: form.strategy };