{"record":{"id":"166408f203b43a62","repo":"ZhuLinsen/daily_stock_analysis","slug":"invalid-persisted-market-light-snapshot-for-norma","errorCode":null,"errorMessage":"invalid persisted market light snapshot for {normalized_region} on {best_trade_date}","messagePattern":"invalid persisted market light snapshot for (.+?) on (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/services/market_light_service.py","lineNumber":114,"sourceCode":"                candidate = MarketLightSnapshot.model_validate(snapshot).model_dump()\n            except Exception as exc:\n                logger.warning(\n                    \"invalid persisted market light snapshot: row_id=%s region=%s trade_date=%s error=%s\",\n                    getattr(row, \"id\", \"?\"),\n                    normalized_region,\n                    trade_date,\n                    exc,\n                )\n                if best_snapshot is None:\n                    invalid_target_error = exc\n                continue\n            if best_snapshot is None:\n                best_snapshot = candidate\n\n    if best_snapshot is not None:\n        return best_snapshot\n    if best_trade_date is not None and invalid_target_error is not None:\n        raise ValueError(\n            f\"invalid persisted market light snapshot for {normalized_region} on {best_trade_date}\"\n        ) from invalid_target_error\n    return None\n\n\ndef _extract_region_snapshot(raw_context_snapshot: Any, region: str) -> Optional[Dict[str, Any]]:\n    if not raw_context_snapshot:\n        return None\n    try:\n        payload = (\n            json.loads(raw_context_snapshot)\n            if isinstance(raw_context_snapshot, str)\n            else raw_context_snapshot\n        )\n    except (TypeError, json.JSONDecodeError):\n        return None\n    if not isinstance(payload, dict):\n        return None","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/market_light_service.py#L96-L132","documentation":"ValueError(f'invalid persisted market light snapshot for {normalized_region} on {best_trade_date}') is raised by the snapshot-history loader in src/services/market_light_service.py when at least one persisted snapshot for the best available trade date exists, but every candidate failed to deserialize/validate (the stored JSON does not match the expected schema), and no valid snapshot for that date survived. The original deserialization error is chained via 'from invalid_target_error'.","triggerScenarios":"Loading market light history where the stored context_snapshot JSON for the target trade date is corrupt, truncated, or was written by an older schema version, and no alternate valid snapshot for that date exists; only then does the loader escalate from 'skip bad snapshot' to raising.","commonSituations":"Schema migrations after upgrading the Market Light snapshot model, partially written rows from a crash mid-save, encoding corruption in the persistence layer, or manual DB edits breaking the JSON structure.","solutions":["Inspect the persisted payload for that region/date: select the raw context_snapshot JSON and try parsing it against the current MarketLightSnapshot schema","If written by an old schema, run the migration/backfill that rewrites or re-derives snapshots, or delete the bad rows so the loader treats the date as absent","Re-generate the snapshot for that trade date via the normal analysis flow and persist it","Wrap history loads in try/except at the caller to degrade to 'no history' rather than failing the whole market light view"],"exampleFix":"# before: corrupt row for 2026-08-13 breaks every load\n# (persisted context_snapshot is truncated JSON)\n\n# after: remove/repair the bad row, then reload\n-- DELETE FROM market_light_history\n-- WHERE region = 'cn' AND trade_date = '2026-08-13';\n# next scheduled run re-persists a valid snapshot","handlingStrategy":"try-catch","validationCode":"from src.schemas.market_light import MarketLightSnapshot\n\ndef is_valid_persisted_snapshot(raw_json: str) -> bool:\n    try:\n        MarketLightSnapshot.model_validate_json(raw_json)\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    snapshot = load_latest_snapshot(region)\nexcept ValueError as exc:\n    if \"invalid persisted market light snapshot\" in str(exc):\n        logger.error(\"corrupt snapshot for %s; rebuilding\", region)\n        snapshot = build_current_snapshot(region)  # regenerate fresh","preventionTips":["Validate snapshots against the current schema right after persistence writes them","Run schema migration/backfill jobs when the snapshot model changes","Keep a repair path: on corruption, delete bad rows and re-run the snapshot build"],"tags":["validation","persistence","market-data","data-corruption","schema-migration"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}