golang/go · error

preprocessed profile entry missing weight

Error message

preprocessed profile entry missing weight

What it means

Thrown when deserializing a preprocessed PGO profile and the scanner reaches clean EOF (scanner.Err() is nil) before the third line of an edge entry — the weight/call-site-offset line — is found. Each edge entry must have three lines: caller name, callee name, then a combined "offset weight" line; this error means the entry is truncated after the callee.

Source

Thrown at src/cmd/internal/pgo/deserialize.go:65

	for scanner.Scan() {
		readStr := scanner.Text()

		callerName := readStr

		if !scanner.Scan() {
			if err := scanner.Err(); err != nil {
				return nil, fmt.Errorf("error reading preprocessed profile: %w", err)
			}
			return nil, fmt.Errorf("preprocessed profile entry missing callee")
		}
		calleeName := scanner.Text()

		if !scanner.Scan() {
			if err := scanner.Err(); err != nil {
				return nil, fmt.Errorf("error reading preprocessed profile: %w", err)
			}
			return nil, fmt.Errorf("preprocessed profile entry missing weight")
		}
		readStr = scanner.Text()

		split := strings.Split(readStr, " ")

		if len(split) != 2 {
			return nil, fmt.Errorf("preprocessed profile entry got %v want 2 fields", split)
		}

		co, err := strconv.Atoi(split[0])
		if err != nil {
			return nil, fmt.Errorf("preprocessed profile error processing call line: %w", err)
		}

		edge := NamedCallEdge{
			CallerName:     callerName,
			CalleeName:     calleeName,
			CallSiteOffset: co,

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the preprocessed profile so every edge entry has all three required lines: caller, callee, and "offset weight".
  2. Check that the file ends with a complete final entry (no partial trailing lines).
  3. Validate the file format against the serializer's output to ensure version compatibility.

Example fix

// Data fix: ensure each entry is 3 lines. Correct format:
// example.com/pkg.Func
// example.com/pkg.Callee
// 42 1000
// (callsite-offset weight)
Defensive patterns

Strategy: validation

Validate before calling

// Check that the file has a complete set of 3-line entries:
func checkProfileCompleteness(path string) error {
    data, err := os.ReadFile(path)
    if err != nil { return err }
    lines := strings.Split(strings.TrimRight(string(data), "\n"), "\n")
    if len(lines) % 3 != 0 {
        return fmt.Errorf("incomplete entry: %d lines is not divisible by 3", len(lines))
    }
    return nil
}

Prevention

When it happens

Trigger: scanner.Scan() returns false with scanner.Err() == nil on the third Scan(), indicating a clean end-of-input. The profile file ends after the callee name line but before the weight line, so the entry is incomplete.

Common situations: A preprocessed profile file that was truncated mid-write, or one that was manually constructed with only two lines per entry instead of three. Also seen when a different serialization format version produced entries with fewer fields.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/1b61a070e604ada4. Report an issue: GitHub.