{"record":{"id":"a244f8b2ae6444e1","repo":"ruvnet/RuView","slug":"unknown-unwrapping-method-self-unwrapping-method","errorCode":null,"errorMessage":"Unknown unwrapping method: {self.unwrapping_method}","messagePattern":"Unknown unwrapping method: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"archive/v1/src/core/phase_sanitizer.py","lineNumber":97,"sourceCode":"        \n        Args:\n            phase_data: Wrapped phase data (2D array)\n            \n        Returns:\n            Unwrapped phase data\n            \n        Raises:\n            PhaseSanitizationError: If unwrapping fails\n        \"\"\"\n        try:\n            if self.unwrapping_method == 'numpy':\n                return self._unwrap_numpy(phase_data)\n            elif self.unwrapping_method == 'scipy':\n                return self._unwrap_scipy(phase_data)\n            elif self.unwrapping_method == 'custom':\n                return self._unwrap_custom(phase_data)\n            else:\n                raise ValueError(f\"Unknown unwrapping method: {self.unwrapping_method}\")\n                \n        except Exception as e:\n            raise PhaseSanitizationError(f\"Failed to unwrap phase: {e}\")\n    \n    def _unwrap_numpy(self, phase_data: np.ndarray) -> np.ndarray:\n        \"\"\"Unwrap phase using numpy's unwrap function.\"\"\"\n        if phase_data.size == 0:\n            raise ValueError(\"Cannot unwrap empty phase data\")\n        return np.unwrap(phase_data, axis=1)\n    \n    def _unwrap_scipy(self, phase_data: np.ndarray) -> np.ndarray:\n        \"\"\"Unwrap phase using scipy's unwrap function.\"\"\"\n        if phase_data.size == 0:\n            raise ValueError(\"Cannot unwrap empty phase data\")\n        return np.unwrap(phase_data, axis=1)\n    \n    def _unwrap_custom(self, phase_data: np.ndarray) -> np.ndarray:\n        \"\"\"Unwrap phase using custom algorithm.\"\"\"","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/core/phase_sanitizer.py#L79-L115","documentation":"ValueError raised by the defensive else branch in PhaseSanitizer.unwrap_phase when self.unwrapping_method matches none of 'numpy'/'scipy'/'custom'. Under normal use this is unreachable because _validate_config rejects invalid methods at construction; it fires only when the attribute is mutated after __init__ or when validation was bypassed. The surrounding except immediately wraps it into PhaseSanitizationError, so callers see error 138's message carrying this text.","triggerScenarios":"Assigning sanitizer.unwrapping_method = 'scipy_unwrap' (or any non-whitelisted value) after construction and then calling unwrap_phase(phase_data). Also reachable in subclasses or tests that skip __init__ (e.g. PhaseSanitizer.__new__) and set attributes manually.","commonSituations":"Hot-swapping the method at runtime based on data characteristics without revalidating; monkeypatching in tests that writes an invalid method name; deserialization code that restores instance attributes from a saved config of a different version without running validation.","solutions":["Never mutate unwrapping_method after construction; create a new PhaseSanitizer instance with the desired method: PhaseSanitizer({**old.config, 'unwrapping_method': 'scipy'}).","If runtime switching is required, keep a dict of pre-built sanitizer instances per method and select among them.","When restoring state from saved config, route through the constructor instead of setattr so _validate_config runs.","In tests, patch via constructing with the method you need rather than overwriting the attribute."],"exampleFix":"# before\nsanitizer.unwrapping_method = 'scipy_v2'   # bypasses validation\nunwrapped = sanitizer.unwrap_phase(phase)   # Unknown unwrapping method\n\n# after\nsanitizer = PhaseSanitizer({**sanitizer.config, 'unwrapping_method': 'scipy'})\nunwrapped = sanitizer.unwrap_phase(phase)","handlingStrategy":"validation","validationCode":"VALID_METHODS = ('numpy', 'scipy', 'custom')\n\ndef switch_method(sanitizer, method: str) -> 'PhaseSanitizer':\n    if method not in VALID_METHODS:\n        raise ValueError(f'{method!r} not in {VALID_METHODS}')\n    return PhaseSanitizer({**sanitizer.config, 'unwrapping_method': method})\n\n# sanitizer = switch_method(sanitizer, 'scipy')  # never mutate the attribute","typeGuard":"from typing import TypeGuard\n\nVALID_METHODS = ('numpy', 'scipy', 'custom')\n\ndef is_valid_unwrap_method(value: object) -> TypeGuard[str]:\n    return isinstance(value, str) and value in VALID_METHODS","tryCatchPattern":"try:\n    unwrapped = sanitizer.unwrap_phase(phase_data)\nexcept PhaseSanitizationError as e:\n    if 'Unknown unwrapping method' in str(e):\n        sanitizer = PhaseSanitizer(sanitizer.config)  # rebuild with validated config\n        unwrapped = sanitizer.unwrap_phase(phase_data)\n    else:\n        raise","preventionTips":["Treat PhaseSanitizer as immutable after construction; rebuild instances to change methods.","Route deserialized/restored state through __init__ so _validate_config runs.","In tests, construct with the desired method instead of monkeypatching the attribute."],"tags":["phase-sanitizer","immutability","defensive-check","runtime"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}