{"record":{"id":"b2baffce12b12c80","repo":"inancgumus/learngo","slug":"record-visits-cannot-be-negative","errorCode":null,"errorMessage":"record.visits cannot be negative","messagePattern":"record\\.visits cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"logparser/v5/pipe/record.go","lineNumber":100,"sourceCode":"\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":82,"sourceCodeEnd":106,"githubUrl":"https://github.com/inancgumus/learngo/blob/3c475a78e54336c6255e925ff66b8ef4da6a2ae7/logparser/v5/pipe/record.go#L82-L106","documentation":"Sentinel validation error from the pipe package's internal validate() guard: a decoded record has a negative visits value. UnmarshalText/UnmarshalJSON will happily decode a negative number for the visits field, so this check rejects input like domain/page/-5/x that is meaningless as a visit counter.","triggerScenarios":"Unmarshaling a record where visits < 0, e.g. \"visits\": -1 in JSON or a text field like \"-5\" parsed as the visits column.","commonSituations":"Diff computations written back to storage producing negative deltas; ETL bugs subtracting counts; manual data edits; overflow/misparse of signed columns.","solutions":["Clamp or correct negative values at the data source before unmarshaling.","Check for ETL/diff logic that subtracts counts and can go below zero.","Skip and report records with negative visits during import.","If negatives are legitimate in your domain, relax the validation check."],"exampleFix":"// before\n{\"domain\":\"example.com\",\"page\":\"/\",\"visits\":-3}\n// after\n{\"domain\":\"example.com\",\"page\":\"/\",\"visits\":0}","handlingStrategy":"validation","validationCode":"if rec.Visits < 0 {\n    rec.Visits = 0 // clamp, or reject the record\n}","typeGuard":"func hasValidVisits(r record) bool { return r.visits >= 0 }","tryCatchPattern":"var rec record\nerr := rec.UnmarshalJSON(data)\nif err != nil {\n    if strings.Contains(err.Error(), \"record.visits cannot be negative\") {\n        log.Printf(\"dropping record with negative visits: %s\", data)\n        return nil\n    }\n    return err\n}","preventionTips":["Clamp counters to zero at the ETL boundary","Audit subtraction-based diff logic for underflow","Validate counters before persisting aggregated data","Add data-quality checks on source columns"],"tags":["validation","logparser","data-quality"],"backgroundTag":"schema-validation-failed","analyzedSha":"3c475a78e54336c6255e925ff66b8ef4da6a2ae7","analyzedAt":"2026-09-02T10:14:38.492Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}