{"record":{"id":"4e425f06a89a0164","repo":"Hmbown/CodeWhale","slug":"version-must-be-a-semantic-release-identifier","errorCode":null,"errorMessage":"version must be a semantic release identifier","messagePattern":"version must be a semantic release identifier","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"integrations/verifiers-codewhale/codewhale_harness/harness.py","lineNumber":98,"sourceCode":"    \"\"\"Preinstalled facade inside the runtime; useful for local candidate testing.\"\"\"\n\n    max_turns: int | None = None\n    \"\"\"Optional model-step ceiling; omitted rollouts are unlimited.\"\"\"\n\n    sandbox: Literal[\"auto\", \"read-only\", \"workspace-write\", \"external-sandbox\"] = (\n        \"auto\"\n    )\n    \"\"\"`auto` keeps subprocess runs workspace-bound and trusts isolated runtimes.\"\"\"\n\n\nclass CodewhaleHarness(Harness[CodewhaleHarnessConfig]):\n    APPENDS_SYSTEM_PROMPT = True\n    SUPPORTS_MCP = True\n    SUPPORTS_USER_SIM = False\n\n    def _validate_config(self) -> None:\n        if not _VERSION.fullmatch(self.config.version):\n            raise ValueError(\"version must be a semantic release identifier\")\n        if (\n            self.config.max_turns is not None\n            and not 1 <= self.config.max_turns <= 10_000\n        ):\n            raise ValueError(\"max_turns must be between 1 and 10000\")\n        invalid = [\n            tool\n            for tool in self.config.disabled_tools or []\n            if not _TOOL.fullmatch(tool)\n        ]\n        if invalid:\n            raise ValueError(\n                \"disabled_tools must use Codewhale catalog identifiers: \"\n                + \", \".join(repr(tool) for tool in invalid)\n            )\n\n    @property\n    def binary(self) -> str:","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/verifiers-codewhale/codewhale_harness/harness.py#L80-L116","documentation":"CodewhaleHarness._validate_config() fullmatches config.version against ^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$ — three numeric segments with an optional prerelease/build tail and no leading 'v'. The version selects the GitHub release the harness installs and pins the stream-json schema it expects (default 0.9.1), so malformed values fail fast in setup() and launch() instead of mid-rollout.","triggerScenarios":"version='v0.9.1' (tag-style leading v), '0.9' (missing patch segment), '0.9.1.2', 'latest', a branch name, or a commit SHA.","commonSituations":"Pasting release tags as displayed on GitHub (they carry the v prefix); feeding git describe output; CI injecting the checked-out ref as the version.","solutions":["Strip any leading 'v' and use exactly three numeric segments, e.g. '0.9.1'","Copy the version from the config default or the release page's plain version string","Validate with the same regex before constructing CodewhaleHarnessConfig"],"exampleFix":"# before\nconfig = CodewhaleHarnessConfig(version='v0.9.1')\n# after\nconfig = CodewhaleHarnessConfig(version='0.9.1')","handlingStrategy":"validation","validationCode":"import re\n_VERSION = re.compile(r'^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$')\nversion = version[1:] if version.startswith('v') else version\nif not _VERSION.fullmatch(version):\n    raise ValueError(f'not a semantic release: {version}')\nconfig = CodewhaleHarnessConfig(version=version)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store bare three-part versions in eval configs","Strip tag prefixes at ingestion time","Pin only versions that exist as GitHub releases with published assets"],"tags":["config","validation","python","versioning","harness"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}