{"record":{"id":"eba822c9a5eb8dc9","repo":"JuliusBrussee/caveman","slug":"experiment-label-must-be-1-128-bytes","errorCode":null,"errorMessage":"experiment label must be 1-128 bytes","messagePattern":"experiment label must be 1-128 bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/store/learn_experiment.go","lineNumber":90,"sourceCode":"type ExperimentReport struct {\n\tSchema     string                `json:\"schema\"`\n\tBasis      string                `json:\"basis\"`\n\tLabel      string                `json:\"label\"`\n\tSinkID     string                `json:\"sink_id,omitempty\"`\n\tFixKind    string                `json:\"fix_kind,omitempty\"`\n\tArms       []ExperimentArmResult `json:\"arms\"`\n\tVerdict    string                `json:\"verdict\"`\n\tDeltaPct   *float64              `json:\"median_session_tokens_delta_pct,omitempty\"`\n\tSavedUSD   *float64              `json:\"saved_usd_per_session,omitempty\"`\n\tCurrency   string                `json:\"currency,omitempty\"`\n\tAttributed LearnAttribution      `json:\"attribution\"`\n\tCaveats    []string              `json:\"caveats\"`\n}\n\nfunc (s *Store) StartExperiment(label, sinkID, fixKind, note string) (Experiment, error) {\n\tlabel = strings.TrimSpace(label)\n\tif label == \"\" || len(label) > 128 {\n\t\treturn Experiment{}, fmt.Errorf(\"experiment label must be 1-128 bytes\")\n\t}\n\tif len(note) > 4096 {\n\t\treturn Experiment{}, fmt.Errorf(\"note exceeds 4096 bytes\")\n\t}\n\tnow := learnOutcomeClock().UTC().Format(time.RFC3339)\n\tresult, err := s.db.Exec(`INSERT INTO experiments (label, sink_id, fix_kind, note, created_at)\n\t\tVALUES (?, ?, ?, ?, ?)`, label, sinkID, fixKind, note, now)\n\tif err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"start experiment %q: %w\", label, err)\n\t}\n\tid, err := result.LastInsertId()\n\tif err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"read experiment id: %w\", err)\n\t}\n\tif _, err := s.db.Exec(`INSERT INTO experiment_arms (experiment_id, arm, started_at)\n\t\tVALUES (?, ?, ?)`, id, experimentArmOn, now); err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"open first arm: %w\", err)\n\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/81536f57b3303b7de7f5bc5b564cc344f9112d68/proxy/internal/store/learn_experiment.go#L72-L108","documentation":"StartExperiment validated the experiment label and found it empty or longer than 128 bytes. The label bounds keep experiment metadata queryable and bounded before any experiment state is created.","triggerScenarios":"Thrown at proxy/internal/store/learn_experiment.go:90 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Provide a non-empty label of at most 128 bytes","Trim accidental whitespace-only labels in the caller","Auto-generate a short slug label when the user supplies none"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"81536f57b3303b7de7f5bc5b564cc344f9112d68","analyzedAt":"2026-08-27T02:25:50.681Z","contentChangedAt":"2026-08-27T02:25:50.681Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}