ZhuLinsen/daily_stock_analysis · warning · Error
Desktop backend URL is unavailable
Error message
Desktop backend URL is unavailable
What it means
Raised by PortfolioService.query_trades when a non-empty symbol filter produces no usable filter values. _build_symbol_filter_values (portfolio_service.py:1299) normalizes the symbol via canonical_stock_code/normalize_stock_code; if normalization yields an empty string, the filter list is empty and the service refuses to run an unfiltered query that the user intended to be filtered.
Source
Thrown at apps/dsa-desktop/main.js:1354
}
function buildMainPageUrl(port, timestamp = Date.now(), host = DESKTOP_BACKEND_DEFAULT_HOST) {
const url = new URL(buildBackendUrl(host, port, '/'));
url.searchParams.set('desktop_version', resolveDesktopVersion() || 'unknown');
url.searchParams.set('cache_bust', String(timestamp));
return url.toString();
}
function buildDesktopShareImageUrl(pageUrl, recordId, expectedBackendOrigin = '') {
if (!Number.isSafeInteger(recordId) || recordId <= 0) {
throw new Error('Invalid share image record ID');
}
let page;
try {
page = new URL(pageUrl);
} catch (_error) {
throw new Error('Desktop backend URL is unavailable');
}
let expectedOrigin = page.origin;
if (expectedBackendOrigin) {
try {
expectedOrigin = new URL(expectedBackendOrigin).origin;
} catch (_error) {
throw new Error('Desktop backend origin is invalid');
}
}
if (page.protocol !== 'http:' || !page.port || page.origin !== expectedOrigin) {
throw new Error('Desktop share images require the configured backend origin');
}
return new URL(
`/api/v1/history/${recordId}/share-image-html`,
page.origin
).toString();View on GitHub (pinned to 5159bd72e8)
Solutions
- Send a real ticker in a supported format ('600519', 'HK00700', 'AAPL')
- If the intent is 'no filter', omit the symbol parameter entirely or pass an empty string
- Validate symbols against the same canonicalizer (data_provider.base.canonical_stock_code) before calling query_trades
- Sanitize upstream data feeds that inject placeholder values into symbol fields
Example fix
# before svc.query_trades(symbol="-") # after svc.query_trades(symbol=None) # no symbol filter
Defensive patterns
Strategy: validation
Validate before calling
from data_provider.base import canonical_stock_code, normalize_stock_code
def symbol_filter_ok(symbol):
if symbol is None or not symbol.strip():
return True # no filter intended
return bool(canonical_stock_code(normalize_stock_code(symbol.strip()))) Type guard
def is_queryable_symbol(symbol: str | None) -> bool:
"""False when query_trades would raise 'symbol is invalid'."""
if not (symbol or "").strip():
return True
return bool(canonical_stock_code(symbol)) Try / catch
try:
svc.query_trades(symbol=s)
except ValueError as exc:
if "symbol is invalid" in str(exc):
return {"items": [], "total": 0} # treat as no matches
raise Prevention
- Omit the symbol param entirely when no filter is wanted
- Use real tickers, never placeholders like '-' or 'n/a'
- Pre-validate filter input with the provider's canonicalizer
When it happens
Trigger: GET /portfolio/trades?symbol=%20%20%20%20 or ?symbol=@@@, or query_trades(symbol="NOSUCH!!!") where canonicalization returns ''. Note the guard is only reached when symbol.strip() is truthy, so purely empty strings skip filtering instead of raising.
Common situations: Passing punctuation-only or placeholder strings ('-', 'n/a', '--') from a CSV import or UI dropdown; symbols containing only whitespace that survived an outer strip but fail canonicalization; test fixtures with invented tickers the provider cannot canonicalize.
Related errors
- Backend executable not found: ${backendPath}
- Invalid share image record ID
- Desktop backend origin is invalid
- Desktop share image has invalid dimensions: ${pageMetrics.wi
- Desktop share images require the configured backend origin
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/9a19ba2d9e4b2f25.
Report an issue: GitHub.