ZhuLinsen/daily_stock_analysis · warning · Error
Desktop backend origin is invalid
Error message
Desktop backend origin is invalid
What it means
Raised by PortfolioService.query_trades when the side filter, after strip+lowercase, is not in VALID_SIDES = {'buy','sell'} (portfolio_service.py:36). The check runs before query_trades hits the repository, so an invalid side never reaches SQL.
Source
Thrown at apps/dsa-desktop/main.js:1362
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();
}
async function renderDesktopShareImage(
recordId,
{
sourceWindow = mainWindow,
BrowserWindowClass = BrowserWindow,
backendOrigin = '',View on GitHub (pinned to 5159bd72e8)
Solutions
- Use exactly 'buy' or 'sell' (case-insensitive) as the side parameter
- If no side filter is wanted, omit the parameter or pass an empty string
- Constrain the UI dropdown / API client enum to the two valid literals
- If migrating from another system, map its side vocabulary ('B'/'S') to 'buy'/'sell' before calling
Example fix
# before svc.query_trades(side="B") # after svc.query_trades(side="buy")
Defensive patterns
Strategy: validation
Validate before calling
VALID_SIDES = {"buy", "sell"}
def side_ok(side):
return side is None or not side.strip() or side.strip().lower() in VALID_SIDES Type guard
from typing import Literal
TradeSide = Literal["buy", "sell"]
def is_trade_side(value: str) -> TypeGuard[TradeSide]:
return value.strip().lower() in {"buy", "sell"} Try / catch
try:
svc.query_trades(side=side)
except ValueError as exc:
if "side must be buy or sell" in str(exc):
raise HTTPBadRequest(detail=str(exc)) from exc
raise Prevention
- Restrict UI dropdowns and API schemas to 'buy'/'sell'
- Map broker B/S codes to the enum in an adapter
- Case does not matter, but the literal words do
When it happens
Trigger: GET /portfolio/trades?side=BUY%2FSELL, ?side=purchase, ?side=trade, or query_trades(side="long"). 'BUY' and 'Buy' are fine because the value is lowercased; anything else raises. Empty/whitespace side is treated as no filter, not an error.
Common situations: Clients sending synonymous terms ('b', 's', 'purchase', 'bought') instead of the enum; enum drift between an older client and the service; form selects with a stale option value after a schema change.
Related errors
- Invalid share image record ID
- Desktop backend URL is unavailable
- Desktop window is unavailable
- Desktop share image capture returned an empty image
- Backend executable not found: ${backendPath}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/5559591ab021bdb3.
Report an issue: GitHub.