Add error message for missing TLD (#12789) (#12796)

* Add error message for missing TLD

* add error code for missing TLD

(cherry picked from commit 321489a41b)

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
github-actions[bot]
2026-09-06 17:03:12 +10:00
committed by GitHub
co-authored by Oliver
parent 5b97accbf3
commit b1b060915e
3 changed files with 45 additions and 1 deletions
+8
View File
@@ -110,6 +110,14 @@ While using [invoke](../start/invoke.md), this can be overridden with the `--res
An error occurred while rendering a component in the frontend. Typically this is caused by a browser caching issue, and can be resolved by clearing the browser cache and refreshing the page. If the issue persists, check the browser console for more information about the error. An error occurred while rendering a component in the frontend. Typically this is caused by a browser caching issue, and can be resolved by clearing the browser cache and refreshing the page. If the issue persists, check the browser console for more information about the error.
#### INVE-E18
**Top Level Domain Required**
The InvenTree server failed to start, because the configured server URL does not include a top-level domain (TLD). A valid TLD is required for proper operation.
## Warning Codes
### INVE-W (InvenTree Warning) ### INVE-W (InvenTree Warning)
Warnings - These are non-critical errors which should be addressed when possible. Warnings - These are non-critical errors which should be addressed when possible.
+2 -1
View File
@@ -28,6 +28,7 @@ from InvenTree.cache import get_cache_config, is_global_cache_enabled
from InvenTree.config import get_boolean_setting, get_oidc_private_key, get_setting from InvenTree.config import get_boolean_setting, get_oidc_private_key, get_setting
from InvenTree.ready import isInMainThread, isRunningBackup from InvenTree.ready import isInMainThread, isRunningBackup
from InvenTree.sentry import default_sentry_dsn, init_sentry from InvenTree.sentry import default_sentry_dsn, init_sentry
from InvenTree.validators import invalid_site_url_hint
from InvenTree.version import checkMinPythonVersion, inventreeCommitHash from InvenTree.version import checkMinPythonVersion, inventreeCommitHash
from users.oauth2_scopes import oauth2_scopes from users.oauth2_scopes import oauth2_scopes
@@ -763,7 +764,7 @@ if SITE_URL:
validator = URLValidator() validator = URLValidator()
validator(SITE_URL) validator(SITE_URL)
except Exception: except Exception:
msg = f"Invalid SITE_URL value: '{SITE_URL}'. InvenTree server cannot start." msg = f"Invalid SITE_URL value: '{SITE_URL}'. InvenTree server cannot start.{invalid_site_url_hint(SITE_URL)}"
logger.error(msg) logger.error(msg)
print(msg) print(msg)
sys.exit(-1) sys.exit(-1)
@@ -1,6 +1,8 @@
"""Custom field validators for InvenTree.""" """Custom field validators for InvenTree."""
import ipaddress
import tokenize import tokenize
from urllib.parse import urlsplit
from django.conf import settings from django.conf import settings
from django.core import validators from django.core import validators
@@ -88,6 +90,39 @@ class AllowedURLValidator(validators.URLValidator):
super().__call__(value) super().__call__(value)
def invalid_site_url_hint(site_url: str) -> str:
"""Return an extra hint for *why* a SITE_URL value failed validation.
Django's URLValidator rejects any hostname that isn't 'localhost', an IP
address, or a fully qualified (dotted) name - so a bare LAN hostname like
'warehouse' fails with no indication of what's actually wrong. Returns an
empty string when nothing more specific than "invalid URL" applies.
"""
hostname = urlsplit(site_url).hostname
if hostname is None and '//' not in site_url:
# No scheme was given at all, e.g. SITE_URL=warehouse
hostname = urlsplit(f'//{site_url}').hostname
if not hostname or hostname == 'localhost':
return ''
try:
ipaddress.ip_address(hostname)
return ''
except ValueError:
pass
if '.' not in hostname:
return (
f"INVE-E17: Top Level Domain Required.\ni'{hostname}' has no top-level domain. InvenTree requires a fully "
"qualified hostname (e.g. 'warehouse.local'), an IP address, or "
"'localhost' - a bare hostname is rejected by Django's URL validator."
)
return ''
def validate_purchase_order_reference(value): def validate_purchase_order_reference(value):
"""Validate the 'reference' field of a PurchaseOrder.""" """Validate the 'reference' field of a PurchaseOrder."""
from order.models import PurchaseOrder from order.models import PurchaseOrder