{"record":{"id":"17208ad6b60b01fa","repo":"JuliusBrussee/caveman","slug":"rewriter-theta-must-not-be-negative-got-d","errorCode":null,"errorMessage":"rewriter: theta must not be negative, got %d","messagePattern":"rewriter: theta must not be negative, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rewriter/rewriter.go","lineNumber":144,"sourceCode":"// gate was designed for.\nfunc New(cfg Config) (*Client, error) {\n\tprovider := strings.ToLower(strings.TrimSpace(cfg.Provider))\n\tif provider != providerAnthropic && provider != providerOpenAI {\n\t\treturn nil, fmt.Errorf(\"rewriter: unsupported provider %q\", cfg.Provider)\n\t}\n\tmodel := strings.TrimSpace(cfg.Model)\n\tif model == \"\" {\n\t\treturn nil, errors.New(\"rewriter: model is required\")\n\t}\n\tif strings.TrimSpace(cfg.APIKey) == \"\" {\n\t\treturn nil, errors.New(\"rewriter: api key is required\")\n\t}\n\ttheta := cfg.Theta\n\tif theta == 0 {\n\t\ttheta = DefaultTheta\n\t}\n\tif theta < 0 {\n\t\treturn nil, fmt.Errorf(\"rewriter: theta must not be negative, got %d\", theta)\n\t}\n\tdoer := cfg.HTTPDoer\n\tif doer == nil {\n\t\tdoer = http.DefaultClient.Do\n\t}\n\treturn &Client{provider: provider, model: model, apiKey: cfg.APIKey, theta: theta, doer: doer}, nil\n}\n\n// Rewrite condenses req.StepBytes, or explains why it did not.\n//\n// Gate 1 (invocation) skips the API call entirely when the step is at or under\n// θ tokens. Gate 2 (application) plus the fidelity checks in Accept decide\n// whether the completion may replace the original. Only an accepted result\n// carries bytes; every other path returns an empty Rewritten and a reason.\nfunc (c *Client) Rewrite(ctx context.Context, req Request) (Result, error) {\n\toriginalTokens := countTokens(req.StepBytes)\n\tif originalTokens <= c.theta {\n\t\treturn Result{RejectReason: reasonBelowTheta}, nil","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/rewriter/rewriter.go#L126-L162","documentation":"rewriter.New accepts cfg.Theta as the rewriting threshold; a zero value is replaced by DefaultTheta, but a negative value is rejected outright. Theta is a sampling/threshold parameter and a negative value has no meaning, so the constructor refuses to build a Client with one.","triggerScenarios":"Calling rewriter.New(Config{Theta: <0}) — e.g. Theta: -1 — typically because the field was populated from user input, a config file, or an int that was defaulted with a sentinel of -1 meaning \"unset\".","commonSituations":"Config files using -1 as \"use default\"; arithmetic producing negative thresholds; copying a config from another tool with different sign conventions; test validation paths (TestNewValidation).","solutions":["Pass a non-negative theta, or leave it 0/omitted so DefaultTheta is applied","Map \"unset\" sentinels (like -1) to 0 before constructing Config","Validate the parsed config value (>= 0) at load time with a clear message","Check sign conventions if porting config from another tool"],"exampleFix":"// before\ncfg := rewriter.Config{Provider: \"openai\", Model: \"m\", Theta: -1} // error\n// after\ntheta := cfgRaw.Threshold\nif theta < 0 {\n    theta = 0 // 0 means DefaultTheta\n}\ncfg := rewriter.Config{Provider: \"openai\", Model: \"m\", Theta: theta}","handlingStrategy":"validation","validationCode":"if cfg.Theta < 0 {\n    return fmt.Errorf(\"theta must be >= 0 (0 selects DefaultTheta=%d), got %d\", rewriter.DefaultTheta, cfg.Theta)\n}","typeGuard":null,"tryCatchPattern":"client, err := rewriter.New(cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"theta must not be negative\") {\n        cfg.Theta = 0 // fall back to DefaultTheta\n        client, err = rewriter.New(cfg)\n    }\n    if err != nil { return err }\n}","preventionTips":["Treat 0 as \"unset -> DefaultTheta\"; never use -1 as a sentinel for unset","Clamp numeric config fields to their domain right after parsing","Add a config-schema check (minimum: 0) for theta in CI","Unit-test config loading with negative values to fail early"],"tags":["config","validation","argument","go"],"backgroundTag":"invalid-argument-value","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"}