ZhuLinsen/daily_stock_analysis · error · Error
发送失败
Error message
发送失败
What it means
Raised during quantity replay (_calculate_available_quantity, portfolio_service.py:749) when a split_adjustment event has split_ratio <= 0 (or null, since null coerces to 0.0). The replay cannot scale holdings by a non-positive factor, so the whole sell-validation/snapshot replay aborts with code=validation_error.
Source
Thrown at apps/dsa-web/src/api/agent.ts:111
const response = await apiClient.get<{ sessions: ChatSessionItem[] }>('/api/v1/agent/chat/sessions', { params: { limit } });
return response.data.sessions;
},
async getChatSessionMessages(sessionId: string): Promise<ChatSessionDetail> {
const response = await apiClient.get<ChatSessionDetail>(`/api/v1/agent/chat/sessions/${sessionId}`);
return response.data;
},
async deleteChatSession(sessionId: string): Promise<void> {
await apiClient.delete(`/api/v1/agent/chat/sessions/${sessionId}`);
},
async sendChat(content: string): Promise<{ success: boolean }> {
const response = await apiClient.post<{
success: boolean;
error?: string;
message?: string;
}>('/api/v1/agent/chat/send', { content });
const data = response.data;
if (data.success === false) {
throw new Error(data.message || '发送失败');
}
return { success: true };
},
async chatStream(
payload: ChatStreamRequest,
options?: ChatStreamOptions,
): Promise<Response> {
const base = API_BASE_URL || '';
const url = `${base}/api/v1/agent/chat/stream`;
try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
credentials: 'include',
signal: options?.signal,
});
View on GitHub (pinned to 5159bd72e8)
Solutions
- Find and fix the offending row: query corporate actions for the symbol where split_ratio IS NULL or <= 0
- Delete the corrupt split_adjustment event if it was created by mistake
- Re-insert valid splits via add_corporate_action, which enforces split_ratio > 0 at write time
- Audit import tooling to skip (not zero-fill) missing split ratios
Example fix
# before svc.add_corporate_action(account_id=1, symbol="AAPL", action_type="split_adjustment", split_ratio=0, ...) # after svc.add_corporate_action(account_id=1, symbol="AAPL", action_type="split_adjustment", split_ratio=2.0, ...)
Defensive patterns
Strategy: validation
Validate before calling
def split_ratio_ok(ratio):
return ratio is not None and ratio > 0 Type guard
from numbers import Real
def is_valid_split_ratio(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 split_ratio" in str(exc):
# quarantine the bad corporate action row and retry
fix_bad_split_rows(a); svc.get_snapshot(account_id=a)
else:
raise Prevention
- Only write corporate actions via add_corporate_action (validates ratio > 0)
- Skip, don't zero-fill, missing split ratios in imports
- Audit corporate_actions for split_ratio <= 0 after bulk loads
When it happens
Trigger: A corporate_actions row with split_ratio = 0, negative, or NULL and action_type='split_adjustment' reaching the replay; rows written by an external tool or manual DB edit that bypassed add_corporate_action's validation; NaN serialized as 0.
Common situations: Manual SQLite/DB fixes that inserted placeholder 0 in split_ratio; import scripts that map a missing split column to 0 instead of skipping the row; an older code path that allowed null split_ratio before validation was added.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/9ddfb960aa14dcfe.
Report an issue: GitHub.