{"record":{"id":"3682e4638818def3","repo":"HKUDS/Vibe-Trading","slug":"delivery-mode-must-be-in-app-origin-or-conf","errorCode":null,"errorMessage":"delivery.mode must be 'in_app', 'origin', or 'configured'","messagePattern":"delivery\\.mode must be 'in_app', 'origin', or 'configured'","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"agent/src/scheduled_research/service.py","lineNumber":183,"sourceCode":"        raise ValueError(\"end_at must be in the future\")\n    if end_at is not None and next_run_at > end_at:\n        raise ValueError(\"the first scheduled run occurs after end_at\")\n\n    mode = str(delivery_spec.get(\"mode\") or \"in_app\")\n    delivery_channel = delivery_target = target_ref = target_label = None\n    if mode == \"configured\":\n        target_ref = str(delivery_spec.get(\"target_ref\") or \"\").strip()\n        if not target_ref:\n            raise ValueError(\"delivery.target_ref is required for configured delivery\")\n        target = resolve_delivery_target(target_ref)\n        delivery_channel, delivery_target = target.channel, target.target\n        target_label = target.label\n    elif mode == \"origin\":\n        delivery_channel, delivery_target, target_ref, target_label = _origin_target(\n            session_id\n        )\n    elif mode != \"in_app\":\n        raise ValueError(\"delivery.mode must be 'in_app', 'origin', or 'configured'\")\n\n    return ScheduledResearchJob(\n        id=str(draft.get(\"id\") or f\"sr-{uuid.uuid4().hex[:12]}\"),\n        title=title,\n        prompt=prompt,\n        source_type=source_type,\n        playbook_slug=playbook_slug,\n        schedule=expression,\n        timezone=timezone,\n        next_run_at=next_run_at,\n        end_at=end_at,\n        status=JobStatus.PENDING,\n        created_at=now,\n        config=config,\n        delivery_channel=delivery_channel,\n        delivery_target=delivery_target,\n        delivery_target_ref=target_ref,\n        delivery_target_label=target_label,","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/scheduled_research/service.py#L165-L201","documentation":"draft.delivery.mode must be one of 'in_app', 'origin', or 'configured' (default 'in_app' when mode is absent). Any other string hits the else branch.","triggerScenarios":"delivery={\"mode\":\"email\"} or 'slack' instead of 'configured'; typos like 'inapp' or 'Origin'; modes from an older schema such as 'webhook'.","commonSituations":"Version drift where delivery modes were renamed; case-sensitive user input; copied examples from other tools using channel names as modes.","solutions":["Use exactly 'in_app', 'origin', or 'configured' (lowercase)","For channel delivery, use mode='configured' with target_ref pointing at the channel target","Omit mode to get 'in_app' by default"],"exampleFix":"// before\n{\"delivery\": {\"mode\": \"slack\"}}\n// after\n{\"delivery\": {\"mode\": \"configured\", \"target_ref\": \"slack-ops\"}}","handlingStrategy":"validation","validationCode":"assert draft.get(\"delivery\", {}).get(\"mode\", \"in_app\") in {\"in_app\", \"origin\", \"configured\"}","typeGuard":"def delivery_mode_valid(d: dict) -> bool:\n    return str(d.get(\"mode\") or \"in_app\") in {\"in_app\", \"origin\", \"configured\"}","tryCatchPattern":"try:\n    propose_create(draft)\nexcept ValueError as e:\n    if \"delivery.mode\" in str(e):\n        draft[\"delivery\"][\"mode\"] = \"in_app\"; retry()","preventionTips":["Model mode as an enum in client code","After upgrades, re-check supported delivery modes in release notes"],"tags":["scheduled-research","delivery","validation","enum"],"backgroundTag":"unsupported-operation-value","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}