router-for-me/CLIProxyAPI · error

line %d: invalid sha256: %w

Error message

line %d: invalid sha256: %w

What it means

The hash field is 64 characters long but contains non-hex characters, so hex.DecodeString fails and ParseChecksums wraps that error with the line number. This catches look-alike corruption: 'O'/'l' substituted for 0/1, stray punctuation, or encoding damage, despite the length passing.

Source

Thrown at internal/pluginstore/checksum.go:26

)

func ParseChecksums(data []byte) (map[string]string, error) {
	out := map[string]string{}
	for lineNumber, rawLine := range strings.Split(string(data), "\n") {
		line := strings.TrimSpace(rawLine)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		fields := strings.Fields(line)
		if len(fields) < 2 {
			return nil, fmt.Errorf("line %d: invalid checksum entry", lineNumber+1)
		}
		hash := strings.ToLower(strings.TrimSpace(fields[0]))
		if len(hash) != sha256.Size*2 {
			return nil, fmt.Errorf("line %d: invalid sha256 length", lineNumber+1)
		}
		if _, errDecode := hex.DecodeString(hash); errDecode != nil {
			return nil, fmt.Errorf("line %d: invalid sha256: %w", lineNumber+1, errDecode)
		}
		name := strings.TrimPrefix(strings.TrimSpace(fields[1]), "*")
		out[name] = hash
	}
	return out, nil
}

func VerifyChecksum(name string, data []byte, checksums map[string]string) error {
	expected := strings.ToLower(strings.TrimSpace(checksums[name]))
	if expected == "" {
		return fmt.Errorf("checksum for %s not found", name)
	}
	actualBytes := sha256.Sum256(data)
	actual := hex.EncodeToString(actualBytes[:])
	if actual != expected {
		return fmt.Errorf("checksum mismatch for %s", name)
	}
	return nil

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Re-copy the hash from the authoritative source without alteration
  2. Regenerate the checksums file directly on the artifacts with sha256sum
  3. Check the file encoding for introduced artifacts (smart quotes, BOM, CRLF mid-line)
Defensive patterns

Strategy: validation

Validate before calling

func hashIsHex64(h string) bool {
    if len(h) != 64 { return false }
    for _, c := range h {
        if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) { return false }
    }
    return true
}

Prevention

When it happens

Trigger: A checksum line whose first field is 64 chars but includes characters outside [0-9a-f], e.g. a hash pasted from a font/rendering that substituted glyphs, or corrupted during file transfer.

Common situations: Copy-paste from a webpage that typographically altered characters; file transferred through a non-binary-safe channel; hand-typed hash with a typo like 'g' or 'O'.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/3c42de2b127e1b12. Report an issue: GitHub.