ZhuLinsen/daily_stock_analysis · error · FileNotFoundError
generated Web index not found: {WEB_INDEX_PATH}
Error message
generated Web index not found: {WEB_INDEX_PATH} What it means
_sync_static_index copies apps/dsa-web/public/stocks.index.json (WEB_INDEX_PATH) into the static assets directory and refuses to continue if the source file does not exist. That index is itself a build artifact produced by this script's earlier generation phase (from data/stock_list_*.csv), so its absence means the generation step was skipped or failed before the sync step.
Source
Thrown at scripts/refresh_stock_index.py:51
def _has_tushare_token() -> bool:
env_path = REPO_ROOT / ".env"
try:
from dotenv import load_dotenv # type: ignore
except ImportError:
if env_path.is_file():
for line in env_path.read_text(encoding="utf-8", errors="ignore").splitlines():
key, sep, value = line.partition("=")
if sep and key.strip() == "TUSHARE_TOKEN" and value.strip().strip("'\""):
return True
return bool(os.getenv("TUSHARE_TOKEN", "").strip())
load_dotenv(env_path)
return bool(os.getenv("TUSHARE_TOKEN", "").strip())
def _sync_static_index() -> None:
if not WEB_INDEX_PATH.is_file():
raise FileNotFoundError(f"generated Web index not found: {WEB_INDEX_PATH}")
STATIC_INDEX_PATH.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(WEB_INDEX_PATH, STATIC_INDEX_PATH)
print(f"[refresh_stock_index] synced {WEB_INDEX_PATH} -> {STATIC_INDEX_PATH}", flush=True)
def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="刷新股票自动补全索引")
parser.add_argument(
"--skip-fetch",
action="store_true",
help="跳过 Tushare 抓取,仅用现有 data/stock_list_*.csv 重新生成索引",
)
args = parser.parse_args(argv)
try:
if args.skip_fetch:
print("[refresh_stock_index] skip Tushare fetch; using existing CSV files")
else:View on GitHub (pinned to 5159bd72e8)
Solutions
- Run the script WITHOUT --skip-fetch once so data/stock_list_*.csv is fetched and apps/dsa-web/public/stocks.index.json is generated.
- If fetch must be skipped, ensure data/stock_list_*.csv already exists (from a previous run) so generation can produce the index before sync.
- Check that apps/dsa-web/public/ exists and is writable; the generator writes the index there.
- If TUSHARE_TOKEN gating skipped the fetch silently, set the token (see error 180) so the full run completes.
Example fix
# before $ python scripts/refresh_stock_index.py --skip-fetch FileNotFoundError: generated Web index not found: .../stocks.index.json # after $ python scripts/refresh_stock_index.py # full run: fetch -> generate -> sync $ python scripts/refresh_stock_index.py --skip-fetch # now safe, CSVs exist
Defensive patterns
Strategy: validation
Validate before calling
from scripts.refresh_stock_index import WEB_INDEX_PATH
from pathlib import Path
if not WEB_INDEX_PATH.is_file():
raise SystemExit("Run full refresh first (no --skip-fetch) to generate stocks.index.json") Type guard
def web_index_ready() -> bool:
return WEB_INDEX_PATH.is_file() Try / catch
try:
_sync_static_index()
except FileNotFoundError:
run_full_refresh() # fetch + generate, then retry sync
_sync_static_index() Prevention
- On fresh clones, run the script once without --skip-fetch before using skip mode.
- Keep data/stock_list_*.csv artifacts from a successful run for later skip-fetch use.
- Ensure TUSHARE_TOKEN is set so the generation phase can actually fetch data.
When it happens
Trigger: Running refresh_stock_index.py --skip-fetch when data/stock_list_*.csv is also absent (nothing to generate the index from, so stocks.index.json is never written); running only the sync portion; the web public dir cleaned (fresh clone, git clean, or dsa-web reinstall wiping public/).
Common situations: First run on a fresh clone without prior fetch output; CI job or wrapper invoking the script with --skip-fetch before any successful full run; stocks.index.json gitignored so a clean checkout lacks it.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/c3d17c40d0e06cd8.
Report an issue: GitHub.