{"record":{"id":"f12bb1f739aa63a1","repo":"JuliusBrussee/caveman","slug":"w-d-bytes-limit-d","errorCode":null,"errorMessage":"%w: %d bytes (limit %d)","messagePattern":"%w: (.+?) bytes \\(limit (.+?)\\)","errorType":"validation","errorClass":"ErrBodyTooLarge","httpStatus":null,"severity":"error","filePath":"shared/platform/redact/payload.go","lineNumber":476,"sourceCode":"//\n// rules are the organization's enabled redaction_rules rows. They are additive\n// only — the built-in floor runs first and cannot be disabled, shadowed, or\n// reordered by anything a tenant configures.\n//\n// The returned slice ALIASES body when no rule fired; body is never mutated\n// (TestPayloadDoesNotMutateInput), so this is safe to read, but a caller that\n// intends to mutate the result in place must copy it first.\n//\n// Payload does not judge how BROAD a rule is. A pattern like \".+\" compiles,\n// matches, and collapses the whole body into one placeholder — a self-inflicted\n// loss of corpus value, not a leak, and the only pattern shapes rejected here\n// are the ones that are unusable rather than merely greedy. Rejecting breadth\n// belongs at rule-write time, where an operator is present to see the error;\n// there is no such surface yet (see the H1 report's concern on the missing\n// redaction_rules validator).\nfunc Payload(body []byte, rules []Rule) ([]byte, RedactionReport, error) {\n\tif len(body) > MaxPayloadBytes {\n\t\treturn nil, RedactionReport{}, fmt.Errorf(\"%w: %d bytes (limit %d)\", ErrBodyTooLarge, len(body), MaxPayloadBytes)\n\t}\n\torgRules, fingerprint, err := compileOrgRules(rules)\n\tif err != nil {\n\t\treturn nil, RedactionReport{}, err\n\t}\n\n\tsum := sha256.Sum256([]byte(builtinRuleSetFingerprint + \"\\x00\" + fingerprint))\n\treport := RedactionReport{\n\t\tRuleSetHash: hex.EncodeToString(sum[:16]),\n\t\tBytesIn:     len(body),\n\t}\n\n\tout := body\n\t// The prescreen is derived ONCE, then re-derived only after a rule whose\n\t// replacement can introduce a needle (see replIntroducesNeedle). Of the\n\t// built-ins only three can, and only when they actually fire.\n\tlowered := asciiLower(out)\n\t// Built-ins first: whatever an org rule does afterwards, it acts on a body","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/redact/payload.go#L458-L494","documentation":"Payload refuses bodies larger than MaxPayloadBytes before doing any redaction work. The error wraps ErrBodyTooLarge so callers can detect oversize input with errors.Is, and reports the actual byte count and the configured limit so the caller knows how far over the ceiling the body is.","triggerScenarios":"Calling shared/platform/redact.Payload with a body whose len(body) exceeds MaxPayloadBytes (the capture ceiling). E.g. passing a multi-MiB request body, or a large adversarial fixture, or any input where the caller skipped its own size pre-check.","commonSituations":"Proxying/logging large uploads without truncating first; a limit lowered via default configuration while traffic still contains big payloads; tests/benchmarks feeding 4MiB+ bodies to probe ceiling behavior.","solutions":["Check len(body) against redact.MaxPayloadBytes before calling Payload and truncate or reject upstream.","Detect the sentinel with errors.Is(err, redact.ErrBodyTooLarge) and surface a clear 'body too large' outcome to your caller.","If larger bodies are legitimate, adjust the capture ceiling in your pipeline before invoking Payload rather than expecting Payload to accept them."],"exampleFix":"// before\nout, report, err := redact.Payload(rawBody, rules)\n// after\nif len(rawBody) > redact.MaxPayloadBytes {\n    rawBody = rawBody[:redact.MaxPayloadBytes]\n}\nout, report, err := redact.Payload(rawBody, rules)","handlingStrategy":"validation","validationCode":"if len(body) > redact.MaxPayloadBytes {\n    return fmt.Errorf(\"refusing to redact: body is %d bytes, limit is %d\", len(body), redact.MaxPayloadBytes)\n}","typeGuard":null,"tryCatchPattern":"out, report, err := redact.Payload(body, rules)\nif errors.Is(err, redact.ErrBodyTooLarge) {\n    // handle oversize body: truncate, drop, or flag\n}","preventionTips":["Enforce a body-size cap at the ingestion boundary before redaction","Keep redact.MaxPayloadBytes and your upstream cap in sync","Add tests with bodies at and above the ceiling"],"tags":["payload","size-limit","redaction","validation"],"backgroundTag":"payload-too-large","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}