{"record":{"id":"bee5d06c1ea9b6cb","repo":"neondatabase/neon","slug":"cannot-find-rel","errorCode":null,"errorMessage":"cannot find 'rel='","messagePattern":"cannot find 'rel='","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pageserver/ctl/src/key.rs","lineNumber":254,"sourceCode":"\n                Ok(KeyMaterial::Split(reltag, blocknum))\n            }\n        }\n    }\n}\n\n#[derive(Debug)]\npub(super) struct SpanAttributesFromLogs(RelTag, BlockNumber);\n\nimpl std::str::FromStr for SpanAttributesFromLogs {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        // accept the span separator but do not require or fail if either is missing\n        // \"whatever{rel=1663/16389/24615 blkno=1052204 req_lsn=FFFFFFFF/FFFFFFFF}\"\n        let (_, reltag) = s\n            .split_once(\"rel=\")\n            .ok_or_else(|| anyhow::anyhow!(\"cannot find 'rel='\"))?;\n        let reltag = reltag.split_whitespace().next().unwrap();\n\n        let (_, blocknum) = s\n            .split_once(\"blkno=\")\n            .ok_or_else(|| anyhow::anyhow!(\"cannot find 'blkno='\"))?;\n        let blocknum = blocknum.split_whitespace().next().unwrap();\n\n        let reltag = reltag\n            .parse()\n            .with_context(|| format!(\"parse reltag from {reltag:?}\"))?;\n        let blocknum = blocknum\n            .parse()\n            .with_context(|| format!(\"parse blocknum from {blocknum:?}\"))?;\n\n        Ok(Self(reltag, blocknum))\n    }\n}\n","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/pageserver/ctl/src/key.rs#L236-L272","documentation":"SpanAttributesFromLogs::from_str extracts a key from a pasted log line such as \"whatever{rel=1663/16389/24615 blkno=1052204 req_lsn=FFFFFFFF/FFFFFFFF}\". It requires the literal marker rel=; without it the parse fails. This error also surfaces nested inside error 210's combined message when the single-argument path tries the log-line parser.","triggerScenarios":"Passing a single argument intended as a log line that lacks the rel= marker.","commonSituations":"Pasting a log line from a context that does not log relation attributes; trimming the line so the rel= token is cut off.","solutions":["Paste a line that includes rel=<tablespace>/<dbnode>/<relnode>, for example rel=1663/16389/24615.","If you only have the raw values, use the multi-argument form instead: pageserver_ctl key 1663/16389/24615 1052204."],"exampleFix":"# before\npageserver_ctl key \"get_page_at_lsn req_lsn=FFFFFFFF/FFFFFFFF\"\n# -> \"cannot find 'rel='\"\n\n# after\npageserver_ctl key \"whatever{rel=1663/16389/24615 blkno=1052204 req_lsn=FFFFFFFF/FFFFFFFF}\"","handlingStrategy":"validation","validationCode":"// before passing a log line, require the markers it needs\nanyhow::ensure!(line.contains(\"rel=\"), \"log line must contain rel=<spc>/<db>/<relnode>\");","typeGuard":"fn log_line_has_rel(line: &str) -> bool {\n    line.contains(\"rel=\")\n}","tryCatchPattern":null,"preventionTips":["Paste log lines from page-reading code paths, which always log rel= and blkno=.","If the line lacks rel=, switch to the multi-argument reltag blocknum form."],"tags":["rust","neon","ctl","key-parsing","log-parsing"],"backgroundTag":"log-line-parse-failed","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}