ZhuLinsen/daily_stock_analysis · error · SystemConfigValidationError
配置校验失败
Error message
配置校验失败
What it means
Raised during full account replay (portfolio_service.py:833) when a trade event has quantity <= 0 or price <= 0 (nulls coerce to 0.0). The replay needs positive qty and price to compute cash impact, cost basis, and PnL; a zero/negative value makes the whole snapshot fail with validation_error.
Source
Thrown at apps/dsa-web/src/api/systemConfig.ts:320
return toCamelCase<DiscoverLLMChannelModelsResponse>(response.data);
},
async update(payload: UpdateSystemConfigRequest): Promise<UpdateSystemConfigResponse> {
try {
const response = await apiClient.put<Record<string, unknown>>(
'/api/v1/system/config',
toSnakeUpdatePayload(payload),
);
return toCamelCase<UpdateSystemConfigResponse>(response.data);
} catch (error: unknown) {
const parsed = getParsedApiError(error);
if (error && typeof error === 'object' && 'response' in error) {
const status = (error as { response?: { status?: number } }).response?.status;
const payloadData = (error as { response?: { data?: unknown } }).response?.data;
if (status === 400) {
const validationError = toCamelCase<SystemConfigValidationErrorResponse>(payloadData ?? {});
throw new SystemConfigValidationError(
parsed.message || validationError.message || '配置校验失败',
validationError.issues || [],
parsed,
);
}
if (status === 409) {
const conflict = toCamelCase<SystemConfigConflictResponse>(payloadData ?? {});
throw new SystemConfigConflictError(
parsed.message || conflict.message || '配置版本冲突',
conflict.currentConfigVersion,
parsed,
);
}
}
throw error;
}View on GitHub (pinned to 5159bd72e8)
Solutions
- Find bad rows: query trades where quantity <= 0 OR price <= 0 OR price IS NULL for the account and fix or delete them
- For transfers/gifts, record a nominal positive price (e.g. cost basis) or model as a buy at the documented cost
- Re-write corrected rows through add_trade to get write-time validation
- Make the importer reject blank/zero prices instead of coercing to 0
Example fix
# before svc.add_trade(account_id=1, symbol="AAPL", side="buy", quantity=10, price=0, ...) # after svc.add_trade(account_id=1, symbol="AAPL", side="buy", quantity=10, price=185.50, ...)
Defensive patterns
Strategy: validation
Validate before calling
def stored_trade_values_ok(qty, price):
return qty is not None and qty > 0 and price is not None and price > 0 Type guard
from numbers import Real
def is_positive_price(value: Real | None) -> bool:
return value is not None and float(value) > 0.0 Try / catch
try:
svc.get_snapshot(account_id=a)
except ValueError as exc:
if "Invalid trade quantity or price" in str(exc):
fix_zero_price_trades(a); svc.get_snapshot(account_id=a)
else:
raise Prevention
- Use a nominal positive price for transfers/gifts, never 0
- Reject blank price columns in importers
- Audit trades for price <= 0 after bulk loads
When it happens
Trigger: A trades row with quantity=0, price=0, price=NULL, or negative values reaching _replay_account; typically rows written by direct DB access or a buggy importer rather than through add_trade, which validates positivity at write time.
Common situations: Gifted/transferred share rows imported with price 0 because the source had no price; CSV import with blank price columns defaulted to 0; dev seeding with placeholder values; fee adjustments mis-modeled as zero-price trades.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/962833e2eddc86f8.
Report an issue: GitHub.