{"record":{"id":"9ce4fe82d655784f","repo":"inancgumus/learngo","slug":"record-page-cannot-be-empty","errorCode":null,"errorMessage":"record.page cannot be empty","messagePattern":"record\\.page cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"logparser/v5/pipe/record.go","lineNumber":98,"sourceCode":"\treturn json.Marshal(rj)\n}\n\n// parseStr helps UnmarshalText for string to positive int parsing.\nfunc parseStr(name, v string) (int, error) {\n\tn, err := strconv.Atoi(v)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"Record.UnmarshalText %q: %v\", name, err)\n\t}\n\treturn n, nil\n}\n\n// validate whether a parsed record is valid or not.\nfunc validate(r record) (err error) {\n\tswitch {\n\tcase r.domain == \"\":\n\t\terr = errors.New(\"record.domain cannot be empty\")\n\tcase r.page == \"\":\n\t\terr = errors.New(\"record.page cannot be empty\")\n\tcase r.visits < 0:\n\t\terr = errors.New(\"record.visits cannot be negative\")\n\tcase r.uniques < 0:\n\t\terr = errors.New(\"record.uniques cannot be negative\")\n\t}\n\treturn\n}\n","sourceCodeStart":80,"sourceCodeEnd":106,"githubUrl":"https://github.com/inancgumus/learngo/blob/3c475a78e54336c6255e925ff66b8ef4da6a2ae7/logparser/v5/pipe/record.go#L80-L106","documentation":"Sentinel validation error from the pipe package's internal validate() guard: after a record is decoded (via UnmarshalText or UnmarshalJSON), the page field is the empty string. It fires because the decoded log record lacks a page path, which the parser requires as a mandatory column alongside domain; the record is rejected before it is aggregated.","triggerScenarios":"UnmarshalText/UnmarshalJSON receive a record where page is missing, null, or \"\" (while domain is non-empty, since domain is checked first).","commonSituations":"Log lines missing the URL/path column; JSON exporters emitting records without the page key; rows where the page was trimmed to nothing.","solutions":["Ensure each record has a non-empty page value before unmarshaling.","Default missing pages to a sentinel like \"/unknown\" if acceptable.","Trim input; if whitespace-only pages should count, fill a value upstream.","Skip and log invalid records instead of failing."],"exampleFix":"// before\n{\"domain\":\"example.com\",\"visits\":10}\n// after\n{\"domain\":\"example.com\",\"page\":\"/\",\"visits\":10}","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(rec.Page) == \"\" {\n    rec.Page = \"/unknown\" // or reject\n}","typeGuard":"func hasPage(r record) bool { return strings.TrimSpace(r.page) != \"\" }","tryCatchPattern":"var rec record\nerr := rec.UnmarshalJSON(data)\nif err != nil {\n    if strings.Contains(err.Error(), \"record.page cannot be empty\") {\n        log.Printf(\"dropping record without page: %s\", data)\n        return nil\n    }\n    return err\n}","preventionTips":["Ensure log exporters always emit the page/path field","Normalize empty paths to \"/\" upstream","Trim fields before unmarshaling","Test with records missing each field individually"],"tags":["validation","logparser","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"3c475a78e54336c6255e925ff66b8ef4da6a2ae7","analyzedAt":"2026-09-02T10:14:38.492Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}