{"record":{"id":"a92baf3e79501e80","repo":"JuliusBrussee/caveman","slug":"close-open-arm-w","errorCode":null,"errorMessage":"close open arm: %w","messagePattern":"close open arm: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/store/learn_experiment.go","lineNumber":135,"sourceCode":"\tif arm != experimentArmOn && arm != experimentArmOff {\n\t\treturn Experiment{}, fmt.Errorf(\"arm must be %q or %q\", experimentArmOn, experimentArmOff)\n\t}\n\texperiment, err := s.LoadExperiment(label)\n\tif err != nil {\n\t\treturn Experiment{}, err\n\t}\n\tif experiment.StoppedAt != \"\" {\n\t\treturn Experiment{}, fmt.Errorf(\"experiment %q is stopped\", experiment.Label)\n\t}\n\tfor _, existing := range experiment.Arms {\n\t\tif existing.EndedAt == \"\" && existing.Arm == arm {\n\t\t\treturn experiment, nil\n\t\t}\n\t}\n\tnow := learnOutcomeClock().UTC().Format(time.RFC3339)\n\tif _, err := s.db.Exec(`UPDATE experiment_arms SET ended_at = ?\n\t\tWHERE experiment_id = ? AND ended_at IS NULL`, now, experiment.id); err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"close open arm: %w\", err)\n\t}\n\tif _, err := s.db.Exec(`INSERT INTO experiment_arms (experiment_id, arm, started_at)\n\t\tVALUES (?, ?, ?)`, experiment.id, arm, now); err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"open arm %q: %w\", arm, err)\n\t}\n\treturn s.LoadExperiment(label)\n}\n\nfunc (s *Store) StopExperiment(label string) (Experiment, error) {\n\texperiment, err := s.LoadExperiment(label)\n\tif err != nil {\n\t\treturn Experiment{}, err\n\t}\n\tnow := learnOutcomeClock().UTC().Format(time.RFC3339)\n\tif _, err := s.db.Exec(`UPDATE experiment_arms SET ended_at = ?\n\t\tWHERE experiment_id = ? AND ended_at IS NULL`, now, experiment.id); err != nil {\n\t\treturn Experiment{}, fmt.Errorf(\"close open arm: %w\", err)\n\t}","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/81536f57b3303b7de7f5bc5b564cc344f9112d68/proxy/internal/store/learn_experiment.go#L117-L153","documentation":"The UPDATE that closes the currently open experiment arm (sets ended_at) failed in SQLite during an arm switch. Input was already valid; this is purely a database-level failure leaving the switch incomplete.","triggerScenarios":"Thrown at proxy/internal/store/learn_experiment.go:135 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the SQLite database is writable and not locked by another process","Inspect the wrapped driver error for the root cause","Retry SwitchExperimentArm once the database is available"],"exampleFix":null,"handlingStrategy":"retry","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-14T00:17:10.932Z"}