{"record":{"id":"25aa29cf0a0081a0","repo":"ZhuLinsen/daily_stock_analysis","slug":"unsupported-report-type","errorCode":"unsupported_report_type","errorMessage":"source report is not a stock analysis report","messagePattern":"source report is not a stock analysis report","errorType":"http","errorClass":"DecisionSignalUnsupportedReportTypeError","httpStatus":400,"severity":"warning","filePath":"src/services/decision_signal_reassess_service.py","lineNumber":208,"sourceCode":"        \"stop_loss\": candidate.stop_loss,\n        \"target_price\": candidate.target_price,\n        \"invalidation\": candidate.invalidation,\n        \"reason\": candidate.reason,\n        \"risk_summary\": candidate.risk_summary,\n        \"watch_conditions\": candidate.watch_conditions,\n        \"metadata\": metadata,\n        \"report_language\": raw_result.get(\"report_language\"),\n    }\n\n\ndef _build_candidate(\n    record: AnalysisHistory,\n    raw_result: Mapping[str, Any],\n    context_snapshot: Mapping[str, Any],\n) -> DecisionSignalCandidate:\n    report_type = str(getattr(record, \"report_type\", \"\") or \"\").strip().lower()\n    if report_type == \"market_review\":\n        raise DecisionSignalUnsupportedReportTypeError(\"source report is not a stock analysis report\")\n\n    raw_code = str(getattr(record, \"code\", \"\") or \"\").strip()\n    market = _infer_market(raw_code)\n    if not raw_code or not market:\n        raise DecisionSignalUnsupportedReportSnapshotError(\"source report has no supported stock identity\")\n\n    dashboard = _as_mapping(raw_result.get(\"dashboard\"))\n    score = _effective_signal_score(\n        _score_from_value(_first_present(raw_result.get(\"sentiment_score\"), getattr(record, \"sentiment_score\", None))),\n        dashboard=dashboard,\n    )\n    raw_action = normalize_decision_action(raw_result.get(\"action\")) or normalize_decision_action(\n        _first_present(raw_result.get(\"operation_advice\"), getattr(record, \"operation_advice\", None))\n    )\n    guardrail_reason = _extract_guardrail_reason(raw_result, score=score, raw_action=raw_action)\n    action_fields = build_action_fields(\n        operation_advice=_first_present(\n            raw_result.get(\"operation_advice\"),","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/decision_signal_reassess_service.py#L190-L226","documentation":"_build_candidate rejects source reports whose report_type is 'market_review' by raising DecisionSignalUnsupportedReportTypeError (code=unsupported_report_type). Market reviews cover the whole market and have no single stock decision, so they cannot produce a per-stock decision signal.","triggerScenarios":"Calling reassess (even preview) with the id of a market-review report — record.report_type == 'market_review' (case-insensitive).","commonSituations":"Frontend reassess button enabled on market-review entries in the history list; batch jobs iterating all history without filtering report_type; users grabbing the newest history id which happens to be a market review.","solutions":["Filter history to individual stock analyses before offering reassess: exclude report_type == 'market_review'.","Use the stock-report list endpoint to select the source report id.","Catch DecisionSignalUnsupportedReportTypeError in batch loops and skip such reports."],"exampleFix":"# before\nresult = service.reassess(source_report_id=any_id, decision_profile=\"balanced\")\n\n# after\nrecord = db.get_analysis_history_by_id(any_id)\nif str(record.report_type or \"\").strip().lower() == \"market_review\":\n    raise ValueError(\"pick a stock analysis report, not a market review\")\nresult = service.reassess(source_report_id=any_id, decision_profile=\"balanced\")","handlingStrategy":"type-guard","validationCode":"report_type = str(getattr(record, \"report_type\", \"\") or \"\").strip().lower()\nif report_type == \"market_review\":\n    return JSONResponse(status_code=422, content={\"error\": \"unsupported_report_type\", \"message\": \"market reviews cannot produce stock signals\"})\nresult = service.reassess(source_report_id=rid, decision_profile=profile)","typeGuard":"def isStockAnalysisReport(record) -> bool:\n    return str(getattr(record, \"report_type\", \"\") or \"\").strip().lower() != \"market_review\"","tryCatchPattern":"from src.services.decision_signal_reassess_service import DecisionSignalUnsupportedReportTypeError\n\ntry:\n    result = service.reassess(source_report_id=rid, decision_profile=profile, persist=persist)\nexcept DecisionSignalUnsupportedReportTypeError:\n    return JSONResponse(status_code=422, content={\"error\": \"unsupported_report_type\", \"message\": \"source report is not a stock analysis report\"})","preventionTips":["Hide the reassess action for market-review entries in the UI.","Batch loops: skip report_type == 'market_review' before calling reassess.","Compare report_type case-insensitively — the service lowercases it."],"tags":["decision-signal","reassess","report-type","validation"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}