{"record":{"id":"fd24586ab86ee36c","repo":"ZhuLinsen/daily_stock_analysis","slug":"stock-code-is-required-fd2458","errorCode":null,"errorMessage":"stock_code is required","messagePattern":"stock_code is required","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"src/services/decision_signal_service.py","lineNumber":1118,"sourceCode":"        return list(dict.fromkeys([normalized, hk_normalized]))\n\n    @classmethod\n    def normalize_stock_code_for_signal(cls, value: Any, *, market: Optional[str] = None) -> str:\n        \"\"\"Normalize a stock code for DecisionSignal identity matching.\"\"\"\n\n        return cls._normalize_stock_code(value, market=market)\n\n    @classmethod\n    def _normalize_stock_code(cls, value: Any, *, market: Optional[str] = None) -> str:\n        raw = str(value or \"\").strip()\n        if market == \"us\":\n            code = canonical_stock_code(raw)\n        elif market == \"hk\":\n            code = cls._normalize_hk_stock_code(raw)\n        else:\n            code = canonical_stock_code(normalize_stock_code(raw))\n        if not code:\n            raise ValueError(\"stock_code is required\")\n        return code\n\n    @staticmethod\n    def _normalize_hk_stock_code(value: str) -> str:\n        normalized = canonical_stock_code(normalize_stock_code(value))\n        digits = \"\"\n        if normalized.startswith(\"HK\"):\n            digits = normalized[2:]\n        elif normalized.isdigit():\n            digits = normalized\n        if digits.isdigit() and 1 <= len(digits) <= 5:\n            return f\"HK{digits.zfill(5)}\"\n        return normalized\n\n    @staticmethod\n    def _normalize_market(value: Any) -> str:\n        market = str(value or \"\").strip().lower()\n        if market not in VALID_MARKETS:","sourceCodeStart":1100,"sourceCodeEnd":1136,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/decision_signal_service.py#L1100-L1136","documentation":"ValueError from DecisionSignalService._normalize_stock_code (src/services/decision_signal_service.py:1118): after stripping and canonicalization (canonical_stock_code / _normalize_hk_stock_code per market), the resulting code is empty, so no stock identity can be established. The market branch decides the canonical form; all branches collapse to '' only when the raw input has no usable content (or normalizers reject it).","triggerScenarios":"create/update signal payloads where stock_code is missing, None, whitespace, or a value that normalizes to empty — e.g. '--', 'N/A', punctuation-only strings. Also HK codes that normalize to a non-digit prefix (e.g. 'HKFOO') still return non-empty, so the empty case is essentially blank/absent input; wrong-market pairing can surface elsewhere.","commonSituations":"Payload built dynamically and the code key is undefined; client sends stock symbol under a different key (symbol/ticker) leaving stock_code blank; CSV/import rows with empty cells; defensive code passing getattr(obj, 'code', None) on objects without that attribute.","solutions":["Make stock_code mandatory in the client payload schema and fail before calling the service.","Map your ticker field to stock_code explicitly when constructing the payload.","For imports, drop or quarantine rows with blank stock_code rather than sending them.","Verify the code format matches the declared market (cn: 6-digit, hk: 1–5 digit payload, us: ticker)."],"exampleFix":"# before\nservice.create_signal({\"market\": \"cn\", \"action\": \"buy\", \"stock_code\": getattr(row, \"ticker\", None)})  # attribute is 'code' → blank → ValueError\n\n# after\nservice.create_signal({\"market\": \"cn\", \"action\": \"buy\", \"stock_code\": row.code})","handlingStrategy":"validation","validationCode":"code = str(payload.get('stock_code') or '').strip()\nif not code:\n    raise ValueError('stock_code missing: fix payload construction before calling the service')","typeGuard":"def has_stock_code(payload: dict) -> bool:\n    return bool(str(payload.get('stock_code') or '').strip())","tryCatchPattern":null,"preventionTips":["Mark stock_code required in the client model; fail at the edge, not in the service.","Map your ticker/symbol field to stock_code explicitly in payload builders.","Quarantine import rows with blank stock codes instead of sending them."],"tags":["decision-signal","validation","required-field","stock-code"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}