{"record":{"id":"d0277d787d88907d","repo":"xai-org/x-algorithm","slug":"post-metadata-is-required-d0277d","errorCode":null,"errorMessage":"Post metadata is required","messagePattern":"Post metadata is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"grox/core/data_loaders/post_mapper.py","lineNumber":52,"sourceCode":"    GrokShareCard,\n    GrokShare,\n    ArticleMetadata,\n    ListMetadata,\n    ChatGroupMetadata,\n    SpaceMetadata,\n    AffiliatedBusiness,\n)\n\nlogger = logging.getLogger(__name__)\n\n\nclass PostMapper:\n    @classmethod\n    def from_strato_post_with_quote_metadata(\n        cls, post_with_quote_metadata: PostWithQuoteMetadata\n    ) -> Post:\n        if not post_with_quote_metadata.post:\n            raise ValueError(\"Post metadata is required\")\n        post = cls.from_post_metadata_strato(post_with_quote_metadata.post)\n        if post_with_quote_metadata.quotedPost:\n            post.quoted_post = cls.from_post_metadata_strato(\n                post_with_quote_metadata.quotedPost\n            )\n        return post\n\n    @classmethod\n    def from_strato_content_understanding_metadata(\n        cls, content_understanding_metadata: ContentUnderstandingMetadataV2\n    ) -> Post:\n        if not content_understanding_metadata.postMetadata:\n            raise ValueError(\"Post metadata is required\")\n        post = cls.from_strato_post_with_quote_metadata(\n            content_understanding_metadata.postMetadata\n        )\n        if content_understanding_metadata.replyThreadPostsMetadata:\n            post.ancestors = [","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/core/data_loaders/post_mapper.py#L34-L70","documentation":"PostMapper.from_strato_post_with_quote_metadata converts a Strato PostWithQuoteMetadata object into the library's Post model. It requires the inner `post` field to be present because all other data (quoted posts, ancestors) hangs off it. If `post_with_quote_metadata.post` is None or missing, the mapper cannot build a Post and raises ValueError immediately.","triggerScenarios":"Calling PostMapper.from_strato_post_with_quote_metadata (directly or via from_strato_content_understanding_metadata / load_post / hydrate) with a PostWithQuoteMetadata instance whose `.post` attribute is None, falsy, or was never populated by the upstream Strato payload.","commonSituations":"Deserializing a truncated or filtered Strato API response; passing a partially-constructed dataclass; upstream schema changes renaming post->postMetadata; test fixtures built without the post field.","solutions":["Check that the source payload actually contains post metadata before mapping: `if not pwqm.post: skip/log`.","Log or inspect the raw PostWithQuoteMetadata to confirm the Strato response isn't empty or filtered.","If building fixtures/tests, populate the `.post` field with a valid PostMetadata instance.","Validate at the boundary where Strato responses enter your system so empty posts are dropped early."],"exampleFix":"// before\npost = PostMapper.from_strato_post_with_quote_metadata(pwqm)  # pwqm.post is None\n\n// after\nif pwqm.post is None:\n    raise ValueError(\"upstream Strato payload missing post metadata\")\npost = PostMapper.from_strato_post_with_quote_metadata(pwqm)","handlingStrategy":"validation","validationCode":"def has_post(pwqm) -> bool:\n    return getattr(pwqm, \"post\", None) is not None","typeGuard":"from grox.core.data_loaders.post_mapper import PostWithQuoteMetadata\n\ndef is_mappable_post(pwqm: PostWithQuoteMetadata) -> bool:\n    return pwqm.post is not None","tryCatchPattern":"try:\n    post = PostMapper.from_strato_post_with_quote_metadata(pwqm)\nexcept ValueError as e:\n    if \"Post metadata is required\" in str(e):\n        log.warning(\"skipping post without metadata: %r\", pwqm)\n        continue\n    raise","preventionTips":["Validate Strato payloads at ingestion and drop entries with missing post metadata.","Build fixtures with factory helpers that always populate post.","Log payload shape when mapping fails to catch schema drift early."],"tags":["python","data-mapping","validation","strato"],"backgroundTag":"required-field-missing","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}