ZhuLinsen/daily_stock_analysis · error · Error
更新尚未下载完成,无法自动安装。
Error message
更新尚未下载完成,无法自动安装。
What it means
Raised by PortfolioService._validate_trade_identity (portfolio_service.py:666) when a trade's dedup_hash already exists for the account. dedup_hash is the content-based duplicate detector for trades that carry no explicit trade_uid; PortfolioConflictError (code=conflict) tells the caller the identical trade is already stored.
Source
Thrown at apps/dsa-desktop/main.js:1589
cancelId: 0,
title: '发现新版本',
message: `检测到桌面端新版本 ${state.latestVersion}`,
detail: `当前版本 ${currentVersion}。新版本将跳转到 GitHub Releases 下载页,不会静默下载或自动安装。`,
noLink: true,
});
if (result.response === 1) {
await shell.openExternal(sanitizeReleaseUrl(state.releaseUrl));
}
}
async function installDownloadedUpdate() {
const updater = getElectronAutoUpdater();
if (!updater) {
throw new Error('当前运行模式不支持自动安装更新。');
}
if (desktopUpdateState?.status !== UPDATE_STATUS.UPDATE_DOWNLOADED) {
throw new Error('更新尚未下载完成,无法自动安装。');
}
setDesktopUpdateState({
status: UPDATE_STATUS.INSTALLING,
updateMode: UPDATE_MODE.AUTO,
latestVersion: desktopUpdateState?.latestVersion || '',
releaseUrl: desktopUpdateState?.releaseUrl || RELEASES_PAGE_URL,
message: '正在重启并安装更新...',
});
let backupRoot = null;
try {
logLine('[update] stop backend and backup runtime data before install');
await stopBackend();
backupRoot = resolveUpdateBackupRoot();
cleanupUpdateBackupRoot();
for (let attempt = 1; attempt <= 3; attempt += 1) {
try {View on GitHub (pinned to 5159bd72e8)
Solutions
- Catch PortfolioConflictError in importers and treat it as already-imported (skip), matching trade_uid semantics
- Compute dedup_hash from all identifying fields (symbol, side, date, quantity, price, fee) so genuine duplicates collide but distinct trades never do
- Make the import job resumable (track last processed row) so full re-runs are unnecessary
- If two truly distinct trades hash the same, fix the hash inputs rather than disabling dedup
Example fix
# before
svc.add_trade(account_id=1, symbol="600519", ...) # no trade_uid
# after
try:
svc.add_trade(account_id=1, symbol="600519", ...)
except PortfolioConflictError as exc:
if "dedup_hash" in str(exc):
continue # already imported Defensive patterns
Strategy: try-catch
Type guard
def dedup_inputs_complete(symbol: str, trade_date, side: str, quantity: float, price: float) -> bool:
"""All identifying fields present, so dedup_hash is well-defined."""
return bool(symbol and trade_date and side in ("buy", "sell") and quantity > 0 and price > 0) Try / catch
from src.services.portfolio_service import PortfolioConflictError
try:
svc.add_trade(account_id=a, ...)
except PortfolioConflictError as exc:
if "dedup_hash" in str(exc):
continue # identical trade already stored; idempotent success
raise Prevention
- Ensure dedup_hash covers all identifying fields so distinct trades never collide
- Catch PortfolioConflictError in any importer and treat as already-imported
- Make import jobs resumable so full re-runs do not resend rows
When it happens
Trigger: add_trade(...) without trade_uid called twice with identical field content (same computed dedup_hash under the same account_id); re-running a CSV import after an interruption; resubmitting a form. The scope is per account, and only when dedup_hash is truthy.
Common situations: Import pipelines restarted mid-file replaying earlier rows; double-clicked form submission; at-least-once queues; a bug in the hash computation that collapses distinct trades (e.g. ignoring quantity) making unrelated trades collide.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/a46545f1f1d49b7c.
Report an issue: GitHub.