{"record":{"id":"6fd5065c4a7524cf","repo":"OpenBMB/ChatDev","slug":"content-cannot-be-empty","errorCode":null,"errorMessage":"content cannot be empty","messagePattern":"content cannot be empty","errorType":"validation","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"entity/configs/node/literal.py","lineNumber":30,"sourceCode":"    require_mapping,\n    require_str,\n)\nfrom entity.messages import MessageRole\n\n\n@dataclass\nclass LiteralNodeConfig(BaseConfig):\n    \"\"\"Config describing the literal payload emitted by the node.\"\"\"\n\n    content: str = \"\"\n    role: MessageRole = MessageRole.USER\n\n    @classmethod\n    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> \"LiteralNodeConfig\":\n        mapping = require_mapping(data, path)\n        content = require_str(mapping, \"content\", path)\n        if not content:\n            raise ConfigError(\"content cannot be empty\", f\"{path}.content\")\n\n        role_value = optional_str(mapping, \"role\", path)\n        role = MessageRole.USER\n        if role_value:\n            normalized = role_value.strip().lower()\n            if normalized not in (MessageRole.USER.value, MessageRole.ASSISTANT.value):\n                raise ConfigError(\"role must be 'user' or 'assistant'\", f\"{path}.role\")\n            role = MessageRole(normalized)\n\n        return cls(content=content, role=role, path=path)\n\n    def validate(self) -> None:\n        if not self.content:\n            raise ConfigError(\"content cannot be empty\", f\"{self.path}.content\")\n        if self.role not in (MessageRole.USER, MessageRole.ASSISTANT):\n            raise ConfigError(\"role must be 'user' or 'assistant'\", f\"{self.path}.role\")\n\n    FIELD_SPECS = {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/entity/configs/node/literal.py#L12-L48","documentation":"LiteralNodeConfig.from_dict requires 'content' to be a truthy string. require_str already enforces string type; this check rejects an empty string, so a literal message node must carry actual text.","triggerScenarios":"Building a literal node from a dict where 'content' is '' (or a string that is empty after being passed through). Missing/non-string 'content' fails earlier in require_str with a different message.","commonSituations":"UI-authored message nodes left blank before saving; templates inserting an empty variable into content; trimming user input down to ''.","solutions":["Provide non-empty text for 'content'","If the value comes from a variable, add a fallback: content or 'placeholder'","Validate user-authored message content before serializing the node config"],"exampleFix":"# before\nLiteralNodeConfig.from_dict({\"content\": \"\"}, path=\"n1\")\n# after\nLiteralNodeConfig.from_dict({\"content\": \"Hello\"}, path=\"n1\")","handlingStrategy":"validation","validationCode":"content = data.get('content')\nif not isinstance(content, str) or not content:\n    raise ValueError('literal content missing')  # or default: data['content'] = '...'","typeGuard":"def has_literal_content(data: dict) -> bool:\n    c = data.get('content')\n    return isinstance(c, str) and bool(c)","tryCatchPattern":"try:\n    LiteralNodeConfig.from_dict(data, path='n1')\nexcept ConfigError as e:\n    if e.path.endswith('content'):\n        data['content'] = '(empty message)'\n        LiteralNodeConfig.from_dict(data, path='n1')\n    else:\n        raise","preventionTips":["Require non-empty text in UI before saving message nodes","Default template variables to placeholder strings","Reject blank content at the authoring layer, not at graph load"],"tags":["config","literal-node","validation","python"],"backgroundTag":"schema-validation-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}