{"record":{"id":"c2a1463c6d6b1837","repo":"nikivdev/code","slug":"missing-pr-title-expected-a-non-empty-line-under","errorCode":null,"errorMessage":"missing PR title (expected a non-empty line under `# Title`)","messagePattern":"missing PR title \\(expected a non-empty line under `# Title`\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pr_edit.rs","lineNumber":615,"sourceCode":"        }\n        if l.trim() == \"# Description\" {\n            while let Some(nl) = lines.peek() {\n                if nl.trim().is_empty() {\n                    lines.next();\n                } else {\n                    break;\n                }\n            }\n            for rest in lines {\n                body_lines.push(rest.to_string());\n            }\n            break;\n        }\n    }\n\n    let title = title.unwrap_or_default().trim().to_string();\n    if title.is_empty() {\n        bail!(\"missing PR title (expected a non-empty line under `# Title`)\");\n    }\n    let body = body_lines.join(\"\\n\").trim_end().to_string();\n    Ok((title, body))\n}\n\nfn write_index(dir: &Path, idx: &IndexFile) -> Result<()> {\n    let path = dir.join(INDEX_FILENAME);\n    let json = serde_json::to_string_pretty(idx)?;\n    std::fs::write(path, json)?;\n    Ok(())\n}\n\n/// Best-effort helper for other codepaths (e.g. `f pr open edit`) to register mappings for files\n/// that don't (yet) have frontmatter.\npub fn index_upsert_file(path: &Path, repo: &str, pr: u64) -> Result<()> {\n    let dir = pr_edit_dir()?;\n    std::fs::create_dir_all(&dir)?;\n    let mut idx = load_index(&dir).unwrap_or_default();","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/pr_edit.rs#L597-L633","documentation":"parse_title_body parses a PR description file that must contain a `# Title` heading followed by a non-empty title line, plus a body. It throws this error when the title section is absent or contains only whitespace, because a PR cannot be created or edited without a title.","triggerScenarios":"Running sync_file on a PR markdown file where the `# Title` heading is missing, or the line(s) under it are empty/whitespace only.","commonSituations":"Hand-edited PR description files where the user deleted the title; templates with a placeholder like `# Title` and nothing beneath it; automated tools that regenerated the file without the title; trailing whitespace that looks like content.","solutions":["Add a non-empty title line directly under the `# Title` heading in the PR file","Verify the heading is exactly `# Title` so the parser recognizes the section","Re-sync or restore the file from the template if the title section was accidentally deleted","Trim stray whitespace-only lines under the heading"],"exampleFix":"// before\n# Title\n\nSome body text...\n// after\n# Title\nAdd support for retrying failed uploads\n\nSome body text...","handlingStrategy":"validation","validationCode":"let content = std::fs::read_to_string(\"PR.md\")?;\nlet has_title = content.lines()\n    .collect::<Vec<_>>()\n    .windows(2)\n    .any(|w| w[0].trim() == \"# Title\" && !w[1].trim().is_empty());\nif !has_title { anyhow::bail!(\"PR file lacks a title under `# Title`\"); }","typeGuard":"fn has_title_section(content: &str) -> bool {\n    let mut lines = content.lines().map(str::trim);\n    while let Some(line) = lines.next() {\n        if line == \"# Title\" {\n            return lines.next().map_or(false, |t| !t.is_empty());\n        }\n    }\n    false\n}","tryCatchPattern":"match parse_title_body(&content) {\n    Ok((title, body)) if !title.is_empty() => sync_file(title, body)?,\n    Err(e) => eprintln!(\"Fix PR file first: {e}\"),\n}","preventionTips":["Always keep a non-empty line directly under `# Title` in PR description files","Start from the official template rather than a blank file","Lint PR markdown files for required sections before syncing","Avoid whitespace-only placeholder lines under the heading"],"tags":["cli","pr","validation","markdown"],"backgroundTag":"missing-required-argument","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}