{"record":{"id":"ca739e7001fb0c41","repo":"sansan0/TrendRadar","slug":"week-map-weekday-day-plan-day-plan-ke","errorCode":null,"errorMessage":"week_map[{weekday}] 引用了不存在的 day_plan: {day_plan_key}","messagePattern":"week_map\\[(.+?)\\] 引用了不存在的 day_plan: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"trendradar/core/scheduler.py","lineNumber":135,"sourceCode":"                push=True,\n                report_mode=self.fallback_report_mode,\n                ai_mode=\"follow_report\",\n                once_analyze=False,\n                once_push=False,\n            )\n\n        now = self.get_time()\n        weekday = now.isoweekday()  # 1=周一 ... 7=周日\n        now_hhmm = now.strftime(\"%H:%M\")\n\n        # 查找当天的日计划\n        day_plan_key = self.timeline[\"week_map\"].get(weekday)\n        if day_plan_key is None:\n            raise ValueError(f\"week_map 缺少星期映射: {weekday}\")\n\n        day_plan = self.timeline[\"day_plans\"].get(day_plan_key)\n        if day_plan is None:\n            raise ValueError(f\"week_map[{weekday}] 引用了不存在的 day_plan: {day_plan_key}\")\n\n        # 查找当前活跃的时间段\n        period_key = self._find_active_period(now_hhmm, day_plan)\n\n        # 合并默认配置和时间段配置\n        merged = self._merge_with_default(period_key)\n\n        # 打印调度日志\n        weekday_names = {1: \"一\", 2: \"二\", 3: \"三\", 4: \"四\", 5: \"五\", 6: \"六\", 7: \"日\"}\n        period_display = \"默认配置（未命中任何时间段）\"\n        if period_key:\n            period_cfg = self.timeline[\"periods\"][period_key]\n            period_name = period_cfg.get(\"name\", period_key)\n            start = period_cfg.get(\"start\", \"?\")\n            end = period_cfg.get(\"end\", \"?\")\n            period_display = f\"{period_name} ({start}-{end})\"\n\n        print(f\"[调度] 星期{weekday_names.get(weekday, '?')}，日计划: {day_plan_key}\")","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/sansan0/TrendRadar/blob/8ee26026ba6c11dec41a95fb3895a7162876caa1/trendradar/core/scheduler.py#L117-L153","documentation":"Raised during resolve() when week_map maps the current weekday to a day_plan key that does not exist in timeline.day_plans. The reference is dangling: the plan was renamed or deleted but week_map still points at the old name. A matching startup check (_validate_timeline) exists, so reaching this at runtime implies validation was bypassed.","triggerScenarios":"Renaming a day_plan (e.g. 'workday' → 'weekday') without updating week_map entries; deleting an unused-looking day_plan that is still referenced; loading externally constructed timelines without validation.","commonSituations":"Hand-editing the schedule config in two places and missing one; YAML indentation moving a plan under a different parent so day_plans keys change.","solutions":["Add the missing day_plan with the exact key week_map references, or update week_map to the new plan name.","Search the timeline config for all references to the renamed plan and update each.","Validate the timeline at startup (call _validate_timeline / rely on the normal startup path) so this surfaces immediately, not mid-run."],"exampleFix":"# before\nweek_map: {1: workday}   # day_plans defines 'weekday'\nday_plans: {weekday: {...}}\n# after\nweek_map: {1: weekday}\nday_plans: {weekday: {...}}","handlingStrategy":"validation","validationCode":"for day, plan_key in timeline[\"week_map\"].items():\n    if plan_key not in timeline[\"day_plans\"]:\n        raise ValueError(\n            f\"week_map[{day}] -> missing day_plan '{plan_key}'\"\n        )\n# run before scheduler.resolve()","typeGuard":"def day_plan_refs_valid(timeline: dict) -> bool:\n    plans = timeline.get(\"day_plans\", {})\n    return all(k in plans for k in timeline.get(\"week_map\", {}).values())","tryCatchPattern":"try:\n    cfg = scheduler.resolve()\nexcept ValueError as e:\n    if \"引用了不存在的 day_plan\" in str(e):\n        # config bug: fix names and rebuild scheduler, do not retry blindly\n        raise SystemExit(f\"schedule config error: {e}\")\n    raise","preventionTips":["Rename day_plans and week_map entries in the same edit.","Add a config lint step (or unit test) that checks week_map→day_plans references."],"tags":["scheduler","config","dangling-reference","runtime"],"backgroundTag":null,"analyzedSha":"8ee26026ba6c11dec41a95fb3895a7162876caa1","analyzedAt":"2026-08-15T01:42:18.084Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}