{"record":{"id":"d7daa6afab05360e","repo":"kubernetes/kops","slug":"unexpected-line-q-expected-2-tokens","errorCode":null,"errorMessage":"unexpected line %q (expected 2 tokens)","messagePattern":"unexpected line %q \\(expected 2 tokens\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/assets/assetdata/tools/cmd/generatefileassets/main.go","lineNumber":90,"sourceCode":"\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif line == \"-----BEGIN PGP SIGNED MESSAGE-----\" {\n\t\t\t// Start of the PGP boilerplate\n\t\t\tcontinue\n\t\t}\n\t\tif line == \"-----BEGIN PGP SIGNATURE-----\" {\n\t\t\t// Part of the PGP signature; end of signed content\n\t\t\tbreak\n\t\t}\n\t\tif line == \"Hash: SHA256\" {\n\t\t\t// Part of the PGP boilerplate\n\t\t\tcontinue\n\t\t}\n\t\ttokens := strings.Fields(line)\n\t\tif len(tokens) != 2 {\n\t\t\treturn fmt.Errorf(\"unexpected line %q (expected 2 tokens)\", line)\n\t\t}\n\t\thash := tokens[0]\n\t\tname := tokens[1]\n\t\tname = removeBadPrefix(name)\n\n\t\tif exclude.Matches(prefix + name) {\n\t\t\tcontinue\n\t\t}\n\t\tm.Files = append(m.Files, file{\n\t\t\tName:   prefix + name,\n\t\t\tSHA256: hash,\n\t\t})\n\t}\n\n\tout, err := yaml.Marshal(&m)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"building yaml: %w\", err)\n\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/assets/assetdata/tools/cmd/generatefileassets/main.go#L72-L108","documentation":"run() parses the SHA256SUMS response line by line, skipping blank lines and known PGP boilerplate. Any non-empty line that does not split into exactly 2 whitespace-separated tokens (hash, filename) is rejected with this error. It guards against HTML error pages, comments, or unexpected formats corrupting the generated manifest.","triggerScenarios":"The URL returned content that isn't a standard SHA256SUMS file: an HTML error/consent page, a GPG file with unhandled boilerplate lines, lines with extra tokens (checksum files with size columns), or wrapped/continuation lines.","commonSituations":"Pointing -sums at a login page or a directory listing; using a BSD-style checksum file or one with additional metadata columns; PGP headers differing from the three handled cases.","solutions":["Inspect the URL content with curl; point -sums at the real plain-text SHA256SUMS file","Preprocess/handle unusual lines: strip comments or extra columns, or extend the parser to skip them","If PGP boilerplate differs, add the marker line to the skip list alongside 'Hash: SHA256'","Verify you downloaded the sha256 (not sha512/md5) sums matching the expected 2-column format"],"exampleFix":"// before: HTML error page fed to parser\nunexpected line \"<html>...\" (expected 2 tokens)\n// after: correct sums URL\nmain -sums https://dl.k8s.io/.../SHA256SUMS ...","handlingStrategy":"validation","validationCode":"func looksLikeSums(b []byte) bool {\n\tfor _, line := range strings.Split(string(b), \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" || strings.HasPrefix(line, \"-----\") || strings.HasPrefix(line, \"Hash:\") || strings.HasPrefix(line, \"<\") {\n\t\t\tcontinue\n\t\t}\n\t\tif len(strings.Fields(line)) != 2 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":"func isUnexpectedLineErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"unexpected line\")\n}","tryCatchPattern":"if err := run(ctx); err != nil {\n\tif isUnexpectedLineErr(err) {\n\t\t// dump the raw response to inspect what was actually fetched\n\t}\n\treturn err\n}","preventionTips":["Curl the sums URL first and confirm it is plain 2-column SHA256SUMS text","Never point -sums at HTML pages or directory listings","Extend the PGP-boilerplate skip list if the signature format changes","Prefer sha256 sums files over checksum formats with extra columns"],"tags":["parsing","checksums","format"],"backgroundTag":"unexpected-checksum-file-format","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}