{"record":{"id":"7316d25ddc685d94","repo":"HKUDS/Vibe-Trading","slug":"max-bytes-must-be-positive-got-max-bytes","errorCode":null,"errorMessage":"max_bytes must be positive, got {max_bytes}","messagePattern":"max_bytes must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"agent/src/governance/ledger.py","lineNumber":649,"sourceCode":"    sealed segment's final ``record_hash`` -- so a deletion of an entire segment\n    is as detectable as an edit within one. Use\n    :func:`verify_chain_with_archives` to check the whole history.\n\n    Args:\n        path: Active ledger path.\n        max_bytes: Size at or above which the active file is sealed.\n        fsync: Whether to fsync the directory after the rename.\n\n    Returns:\n        The archive path when a rotation happened, else None.\n\n    Raises:\n        ValueError: If ``max_bytes`` is not positive.\n        LedgerCorruptionError: If the active chain is broken -- a corrupt\n            ledger is sealed by nobody; fix or quarantine it deliberately.\n    \"\"\"\n    if max_bytes <= 0:\n        raise ValueError(f\"max_bytes must be positive, got {max_bytes}\")\n    if not path.exists() or path.stat().st_size < max_bytes:\n        return None\n\n    result = verify_chain(path)\n    if not result.ok:\n        raise LedgerCorruptionError(result.first_break)\n\n    counter = len(archive_segments(path)) + 1\n    archive = path.with_name(f\"{path.stem}.{counter:0{ARCHIVE_SUFFIX_WIDTH}d}{path.suffix}\")\n    path.rename(archive)\n    if fsync:\n        _fsync_dir(path.parent)\n    return archive\n\n\ndef verify_chain_with_archives(path: Path) -> ChainVerificationResult:\n    \"\"\"Verify a ledger's whole history, sealed segments included.\n","sourceCodeStart":631,"sourceCodeEnd":667,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/governance/ledger.py#L631-L667","documentation":"rotate_if_needed validates its size threshold; max_bytes <= 0 (zero or negative) is rejected because rotation would either never trigger or loop.","triggerScenarios":"Calling rotate_if_needed(path, max_bytes=0) or a negative value, often from a config default of 0 meaning 'unset'.","commonSituations":"Config reads max_bytes from an env var that defaults to 0; unit under test passes -1 as a sentinel; CLI arg parsed as int with missing validation.","solutions":["Default the config to a sane positive size (e.g. 10 * 1024 * 1024) when unset/0","Validate max_bytes > 0 at config load time with a clear error","Treat 0/negative as 'rotation disabled' in your wrapper and skip the call"],"exampleFix":"# before\nrotate_if_needed(path, max_bytes=config.max_bytes)  # config.max_bytes == 0\n# after\nif config.max_bytes and config.max_bytes > 0:\n    rotate_if_needed(path, max_bytes=config.max_bytes)","handlingStrategy":"validation","validationCode":"if max_bytes is None or max_bytes <= 0:\n    max_bytes = 10 * 1024 * 1024  # or skip rotation","typeGuard":"def is_valid_max_bytes(max_bytes: int) -> bool:\n    return isinstance(max_bytes, int) and max_bytes > 0","tryCatchPattern":"except ValueError as e: if 'max_bytes' in str(e): fall back to the default threshold and retry","preventionTips":["Validate rotation config at load time","Use a positive sentinel default, not 0, for 'unset'","Cover config parsing with unit tests"],"tags":["ledger","rotation","invalid-argument","config","python"],"backgroundTag":"invalid-argument-value","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}