{"record":{"id":"8ef253512d306ae1","repo":"ZhuLinsen/daily_stock_analysis","slug":"field-name-is-required","errorCode":null,"errorMessage":"{field_name} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"src/services/decision_signal_service.py","lineNumber":1210,"sourceCode":"    def _optional_text(value: Any, field_name: str, *, max_length: int) -> Optional[str]:\n        if value is None:\n            return None\n        text = str(value).strip()\n        if not text:\n            return None\n        if len(text) > max_length:\n            raise ValueError(f\"{field_name} must be at most {max_length} characters\")\n        return text\n\n    @classmethod\n    def _optional_public_text(cls, value: Any, field_name: str, *, max_length: int) -> Optional[str]:\n        return cls._public_text(value, field_name, max_length=max_length, required=False)\n\n    @staticmethod\n    def _public_text(value: Any, field_name: str, *, max_length: int, required: bool) -> Optional[str]:\n        if value is None:\n            if required:\n                raise ValueError(f\"{field_name} is required\")\n            return None\n        text = sanitize_decision_signal_text(value)\n        if not text:\n            if required:\n                raise ValueError(f\"{field_name} is required\")\n            return None\n        if len(text) > max_length:\n            raise ValueError(f\"{field_name} must be at most {max_length} characters\")\n        return text\n\n    @classmethod\n    def _optional_identity_text(cls, value: Any, field_name: str, *, max_length: int) -> Optional[str]:\n        text = cls._optional_text(value, field_name, max_length=max_length)\n        if text is None:\n            return None\n        sanitized = sanitize_decision_signal_text(text)\n        if any(marker in sanitized for marker in REDACTION_MARKERS):\n            raise ValueError(f\"{field_name} must not contain sensitive credentials\")","sourceCodeStart":1192,"sourceCodeEnd":1228,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/decision_signal_service.py#L1192-L1228","documentation":"ValueError from DecisionSignalService._public_text (src/services/decision_signal_service.py:1210) when required=True and the raw value is None. Required public-text fields (trigger_source is the main one) must be present; this is the None branch — contrast with the line-1215 branch where the value exists but sanitizes to empty. Same message, two distinct causes in the same helper.","triggerScenarios":"create-signal payload where trigger_source (or any required public text) key is absent or explicitly None. Dynamic payload construction that conditionally sets the key only when a condition holds, leaving it missing on some paths.","commonSituations":"Optional/required confusion: the field looks optional in older API versions but became mandatory; kwargs-based builders that drop falsy values (payload = {k: v for k, v in data.items() if v}); schema-first clients omitting the field.","solutions":["Always include a concrete non-empty trigger_source (or the relevant required field) in create payloads.","Fix payload builders that filter out falsy values — use `if v is not None` instead of `if v`.","setdefault a sensible constant per producer before the service call.","Add client-side schema validation marking the field required."],"exampleFix":"# before\npayload = {k: v for k, v in raw.items() if v}  # drops trigger_source when falsy → ValueError\nservice.create_signal(payload)\n\n# after\npayload = {k: v for k, v in raw.items() if v is not None}\npayload.setdefault(\"trigger_source\", \"manual\")\nservice.create_signal(payload)","handlingStrategy":"validation","validationCode":"if not payload.get('trigger_source'):\n    raise ValueError('trigger_source is required — include a non-empty value')","typeGuard":"def payload_has_required_text(payload: dict, field: str) -> bool:\n    return payload.get(field) is not None and str(payload[field]).strip() != ''","tryCatchPattern":null,"preventionTips":["Build payloads with `if v is not None` filters, never truthiness filters.","setdefault a producer-specific constant for required text fields.","Declare required fields in the client schema so omissions fail locally."],"tags":["decision-signal","validation","required-field","public-text"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}