{"record":{"id":"5116435247a409c5","repo":"risingwavelabs/risingwave","slug":"failed-to-decode-prost-field-not-found-511643","errorCode":null,"errorMessage":"Failed to decode prost: field not found `{}`","messagePattern":"Failed to decode prost: field not found `(.+?)`","errorType":"exception","errorClass":"MetadataModelError","httpStatus":null,"severity":"error","filePath":"src/meta/src/model/error.rs","lineNumber":37,"sourceCode":"\npub type MetadataModelResult<T> = std::result::Result<T, MetadataModelError>;\n\n#[derive(Error, Debug)]\npub enum MetadataModelError {\n    #[error(\"Pb decode error: {0}\")]\n    PbDecode(#[from] prost::DecodeError),\n\n    #[error(transparent)]\n    InternalError(\n        #[from]\n        #[backtrace]\n        anyhow::Error,\n    ),\n}\n\nimpl From<PbFieldNotFound> for MetadataModelError {\n    fn from(p: PbFieldNotFound) -> Self {\n        MetadataModelError::InternalError(anyhow::anyhow!(\n            \"Failed to decode prost: field not found `{}`\",\n            p.0\n        ))\n    }\n}\n\nimpl From<MetadataModelError> for tonic::Status {\n    fn from(e: MetadataModelError) -> Self {\n        e.to_status(tonic::Code::Internal, \"meta\")\n    }\n}\n\nimpl MetadataModelError {\n    pub fn internal(msg: impl ToString) -> Self {\n        MetadataModelError::InternalError(anyhow!(msg.to_string()))\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/model/error.rs#L19-L55","documentation":"This converts a `PbFieldNotFound` into `MetadataModelError::InternalError` with the message 'Failed to decode prost: field not found'. It fires when generated protobuf accessor code is invoked for a field that the decoded message does not contain — usually a schema mismatch where the stored/parsed message predates a field that the code assumes exists.","triggerScenarios":"Calling a generated getter `get_<field>()` on a prost message where the optional/oneof field is unset, e.g. decoding an old-format metadata object then reading a newly added required field.","commonSituations":"Version skew: newer code reading metadata written by an older RisingWave that lacked the field; incomplete DDL/migration leaving partial metadata records; hand-edited or replayed protobuf payloads in tests.","solutions":["Align versions across all RisingWave components so the metadata schema includes the field being read.","Make the access defensive: use `field` (Option-returning) instead of `get_field` and handle the None case explicitly.","Recreate the affected metadata object if it predates the schema addition and cannot be backfilled.","Add a migration/backfill step when introducing new required metadata fields."],"exampleFix":"// before\nlet id = object.get_id().unwrap(); // panics/errors if absent\n// after\nlet id = object.id.ok_or_else(|| MetadataModelError::from(PbFieldNotFound(\"id\")))?;","handlingStrategy":"type-guard","validationCode":"// Use Option-returning accessor instead of get_xxx\nlet field = msg.field.as_ref()\n    .ok_or_else(|| anyhow!(\"field not present; metadata written by older version\"))?;","typeGuard":"fn has_field<'a, T>(opt: &'a Option<T>) -> Option<&'a T> {\n    opt.as_ref()\n}","tryCatchPattern":"match decode_and_use_model(bytes).await {\n    Err(MetadataModelError::InternalError(e))\n        if e.to_string().contains(\"field not found\") => {\n        tracing::error!(\"metadata predates schema; backfill or recreate object: {e:#}\");\n    }\n    other => { /* normal handling */ }\n}","preventionTips":["Prefer Option-returning prost accessors over get_xxx for newly added fields","Add migrations/backfills when introducing required metadata fields","Avoid reading metadata written by older versions without a compatibility path"],"tags":["rust","meta","protobuf","schema-mismatch","metadata-model"],"backgroundTag":"schema-validation-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}