plandex-ai/plandex · error

error extracting line number from last line: %v

Error message

error extracting line number from last line: %v

What it means

When the old block spans multiple lines, the last line must also carry a valid 'pdx-<num>' prefix to delimit the replacement range. This error is returned when ExtractLineNumberWithPrefix fails on the last line.

Source

Thrown at app/server/model/plan/build_validate_and_fix.go:413

		var lastLine string
		var lastLineNum int
		firstLine := oldLines[0]
		if len(oldLines) > 1 {
			lastLine = oldLines[len(oldLines)-1]
		}

		firstLineNum, err := shared.ExtractLineNumberWithPrefix(firstLine, "pdx-")
		if err != nil {
			log.Printf("Error extracting line number from first line: %v", err)
			return buildValidateResult{valid: false, updated: updated}, fmt.Errorf("error extracting line number from first line: %v", err)
		}

		if lastLine != "" {
			lastLineNum, err = shared.ExtractLineNumberWithPrefix(lastLine, "pdx-")
			if err != nil {
				log.Printf("Error extracting line number from last line: %v", err)
				return buildValidateResult{valid: false, updated: updated}, fmt.Errorf("error extracting line number from last line: %v", err)
			}
		}

		if lastLineNum == 0 {
			if !(firstLineNum > 0 && firstLineNum <= len(originalFileLines)) {
				log.Printf("Invalid line number for first line: %d", firstLineNum)
				return buildValidateResult{valid: false, updated: updated}, fmt.Errorf("invalid line number for first line: %d", firstLineNum)
			}
			old = originalFileLines[firstLineNum-1]
		} else {
			if !(firstLineNum > 0 && firstLineNum <= len(originalFileLines) && lastLineNum > firstLineNum && lastLineNum <= len(originalFileLines)) {
				log.Printf("Invalid line numbers for first and last lines: %d-%d", firstLineNum, lastLineNum)
				return buildValidateResult{valid: false, updated: updated}, fmt.Errorf("invalid line numbers: %d-%d", firstLineNum, lastLineNum)
			}
			old = strings.Join(originalFileLines[firstLineNum-1:lastLineNum], "\n")
		}

		// log.Printf("Applying replacement.\n\nOld:\n\n%s\n\nNew:\n\n%s", old, new)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Retry so the model regenerates the range with both endpoints prefixed
  2. Strengthen the prompt to require 'pdx-N' on both first and last lines
  3. Add a response pre-check that rejects ranges missing the last-line prefix before reaching this code

Example fix

// before
old = "pdx-10 func main() {\n}\"  // last line unprefixed
// after
old = "pdx-10 func main() {\npdx-12 }\"
Defensive patterns

Strategy: validation

Validate before calling

lines := strings.Split(old, "\n")
if len(lines) > 1 {
    if _, err := shared.ExtractLineNumberWithPrefix(lines[len(lines)-1], "pdx-"); err != nil {
        return fmt.Errorf("last line of old block missing valid pdx- prefix")
    }
}

Type guard

func validRangeBlock(old string) bool {
    lines := strings.Split(old, "\n")
    if len(lines) < 2 { return true }
    _, err := shared.ExtractLineNumberWithPrefix(lines[len(lines)-1], "pdx-")
    return err == nil
}

Prevention

When it happens

Trigger: Multi-line old block whose last line lacks a parseable line number after a valid 'pdx-' prefix (or no prefix at all on the last line).

Common situations: Model correctly prefixes the first line but forgets the last, or the last line is a partial/duplicated hunk.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/f21a1b320a53ddc9. Report an issue: GitHub.