{"record":{"id":"38a8594e9d31cdb9","repo":"risingwavelabs/risingwave","slug":"no-fragment-connection-from-source-fragment-to","errorCode":null,"errorMessage":"no fragment connection from source fragment {} to source backfill fragment {}","messagePattern":"no fragment connection from source fragment (.+?) to source backfill fragment (.+?)","errorType":"exception","errorClass":"MetaError","httpStatus":null,"severity":"error","filePath":"src/meta/src/controller/fragment.rs","lineNumber":1747,"sourceCode":"    /// (`backfill_actor_id`, `upstream_source_actor_id`)\n    pub async fn get_running_actors_for_source_backfill(\n        &self,\n        source_backfill_fragment_id: FragmentId,\n        source_fragment_id: FragmentId,\n    ) -> MetaResult<Vec<(ActorId, ActorId)>> {\n        let inner = self.inner.read().await;\n        let txn = inner.db.begin().await?;\n\n        let fragment_relation: DispatcherType = FragmentRelation::find()\n            .select_only()\n            .column(fragment_relation::Column::DispatcherType)\n            .filter(fragment_relation::Column::SourceFragmentId.eq(source_fragment_id))\n            .filter(fragment_relation::Column::TargetFragmentId.eq(source_backfill_fragment_id))\n            .into_tuple()\n            .one(&txn)\n            .await?\n            .ok_or_else(|| {\n                anyhow!(\n                    \"no fragment connection from source fragment {} to source backfill fragment {}\",\n                    source_fragment_id,\n                    source_backfill_fragment_id\n                )\n            })?;\n\n        if fragment_relation != DispatcherType::NoShuffle {\n            return Err(anyhow!(\"expected NoShuffle but got {:?}\", fragment_relation).into());\n        }\n\n        let load_fragment_distribution_type = |txn, fragment_id: FragmentId| async move {\n            let result: MetaResult<DistributionType> = try {\n                FragmentModel::find_by_id(fragment_id)\n                    .select_only()\n                    .column(fragment::Column::DistributionType)\n                    .into_tuple()\n                    .one(txn)\n                    .await","sourceCodeStart":1729,"sourceCodeEnd":1765,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/controller/fragment.rs#L1729-L1765","documentation":"During creation of a source backfill (streaming job rewrite), the code looks up a fragment_relation row from source_fragment_id to the source backfill fragment; if none exists it returns 'no fragment connection from source fragment {} to source backfill fragment {}'. The persisted fragment graph lacks the mandatory NoShuffle dispatch edge these fragments must have.","triggerScenarios":"Applying a source backfill rewrite for a table whose persisted fragment relations do not contain the expected source→source-backfill edge — e.g. meta data written by an older RisingWave version, partial write of the relation table, or a corrupted/edited meta store.","commonSituations":"Cluster upgraded across versions where backfill fragment layout changed; source backfill triggered on a table created before a migration; manual meta DB edits; interrupted DDL that wrote fragments without relations.","solutions":["Check fragment_relation rows for the reported source_fragment_id in the meta DB to see what edges exist","Verify cluster and table were created with a version supporting source backfill (upgrade if older)","Retry the operation; if the relation row is genuinely missing, the table's metadata is corrupted and may need recreation","Contact RisingWave support / file an issue with the job id and fragment ids if stock writes lose the relation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let rel = fragment_relation::Entity::find()\n    .filter(fragment_relation::Column::SourceFragmentId.eq(src))\n    .filter(fragment_relation::Column::TargetFragmentId.eq(dst))\n    .one(&db).await?;\nif rel.is_none() { return Err(skip_backfill()); }","typeGuard":null,"tryCatchPattern":"match create_source_backfill(...).await { Err(e) if e.to_string().contains(\"no fragment connection\") => log_corrupt_metadata(job_id), other => other }","preventionTips":["Keep the cluster on versions whose backfill fragment layout matches the data","Never hand-edit the meta store","Verify fragment_relation rows exist after migrations"],"tags":["fragment","backfill","metadata","not-found"],"backgroundTag":"record-not-found","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"}