{"record":{"id":"c21e634b28fa88b0","repo":"babysor/MockingBird","slug":"both-increase-only-and-decrease-only-are-set","errorCode":null,"errorMessage":"Both increase only and decrease only are set","messagePattern":"Both increase only and decrease only are set","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"models/encoder/audio.py","lineNumber":113,"sourceCode":"    def moving_average(array, width):\n        array_padded = np.concatenate((np.zeros((width - 1) // 2), array, np.zeros(width // 2)))\n        ret = np.cumsum(array_padded, dtype=float)\n        ret[width:] = ret[width:] - ret[:-width]\n        return ret[width - 1:] / width\n    \n    audio_mask = moving_average(voice_flags, vad_moving_average_width)\n    audio_mask = np.round(audio_mask).astype(bool)\n    \n    # Dilate the voiced regions\n    audio_mask = binary_dilation(audio_mask, np.ones(vad_max_silence_length + 1))\n    audio_mask = np.repeat(audio_mask, samples_per_window)\n    \n    return wav[audio_mask == True]\n\n\ndef normalize_volume(wav, target_dBFS, increase_only=False, decrease_only=False):\n    if increase_only and decrease_only:\n        raise ValueError(\"Both increase only and decrease only are set\")\n    dBFS_change = target_dBFS - 10 * np.log10(np.mean(wav ** 2))\n    if (dBFS_change < 0 and increase_only) or (dBFS_change > 0 and decrease_only):\n        return wav\n    return wav * (10 ** (dBFS_change / 20))\n","sourceCodeStart":95,"sourceCodeEnd":118,"githubUrl":"https://github.com/babysor/MockingBird/blob/28dc5e14f12d7c754612af2fde8e78a4b03f8616/models/encoder/audio.py#L95-L118","documentation":"Raised by normalize_volume when both increase_only=True and decrease_only=True are passed. These flags are mutually exclusive: each restricts volume normalization to one direction, so requesting both is contradictory and indicates a caller bug.","triggerScenarios":"Calling normalize_volume(wav, target_dBFS, increase_only=True, decrease_only=True), directly or via a wrapper that forwards user flags blindly.","commonSituations":"Copy-pasted argument lists; CLI flags mapping both booleans to True; refactors that default both flags on.","solutions":["Remove one of the two flags — decide whether you want the level only raised or only lowered","Pass neither flag to allow normalization in both directions","Add argument validation upstream (e.g. argparse mutually exclusive group)"],"exampleFix":"# before\nnormalize_volume(wav, target_dBFS=-30, increase_only=True, decrease_only=True)\n# after\nnormalize_volume(wav, target_dBFS=-30, increase_only=True)","handlingStrategy":"type-guard","validationCode":"if increase_only and decrease_only:\n    raise ValueError('increase_only and decrease_only are mutually exclusive')\nwav = normalize_volume(wav, target_dBFS, increase_only=increase_only, decrease_only=decrease_only)","typeGuard":"def valid_volume_flags(increase_only: bool, decrease_only: bool) -> bool:\n    return not (increase_only and decrease_only)","tryCatchPattern":"try:\n    normalize_volume(wav, target, increase_only, decrease_only)\nexcept ValueError as e:\n    # caller bug: fix flag wiring, do not retry\n    raise","preventionTips":["Use argparse mutually exclusive groups for such flags","Never forward both booleans from user config blindly","Unit-test the invalid combination"],"tags":["python","audio","argument-validation","valueerror"],"backgroundTag":"mutually-exclusive-arguments","analyzedSha":"28dc5e14f12d7c754612af2fde8e78a4b03f8616","analyzedAt":"2026-08-27T02:26:53.589Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}