{"record":{"id":"95ffb49d99f026a8","repo":"can1357/oh-my-pi","slug":"scheme-must-be-a-non-empty-string","errorCode":null,"errorMessage":"scheme must be a non-empty string","messagePattern":"scheme must be a non-empty string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/omp-rpc/src/omp_rpc/host_uris.py","lineNumber":85,"sourceCode":"    description: str | None = None\n    immutable: bool = False\n\n    @property\n    def writable(self) -> bool:\n        return self.write is not None\n\n\ndef host_uri(\n    *,\n    scheme: str,\n    read: HostUriReadHandler,\n    write: HostUriWriteHandler | None = None,\n    description: str | None = None,\n    immutable: bool = False,\n) -> HostUri[None]:\n    cleaned = (scheme or \"\").strip().lower()\n    if not cleaned:\n        raise ValueError(\"scheme must be a non-empty string\")\n    return HostUri(\n        scheme=cleaned,\n        read=read,\n        write=write,\n        description=description,\n        immutable=immutable,\n    )\n\n\ndef normalize_read_result(value: HostUriReadValue) -> JsonObject:\n    \"\"\"Convert a handler's `read` return into the wire-frame fields.\n\n    Returns a dict suitable for spreading into a `host_uri_result` payload.\n    \"\"\"\n\n    if isinstance(value, str):\n        return {\"content\": value}\n    if not isinstance(value, dict):","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/omp-rpc/src/omp_rpc/host_uris.py#L67-L103","documentation":"host_uri() registers a custom URI scheme (e.g. 'omp://...') with the host, and it refuses to register a scheme that is empty or whitespace-only. The scheme is cleaned via `(scheme or '').strip().lower()` before validation, so None, empty strings, and strings of only spaces all fail. This is an upfront programmer-error guard so registrations with typos or unpopulated variables fail loudly instead of producing unusable URIs.","triggerScenarios":"Calling host_uri('') or host_uri(None), passing a scheme read from an unset config/env variable that resolves to an empty string, or a scheme variable populated via a lookup that returned '' (e.g. dict.get('scheme') missing). Note whitespace-only strings like '   ' also trigger it after stripping.","commonSituations":"Config files with `scheme:` left blank, env vars like OMP_URI_SCHEME unset and defaulted to '', f-string/format placeholders that stayed empty, or a refactoring that split the scheme out of a full URI string but produced an empty prefix.","solutions":["Pass a non-empty literal scheme string, e.g. host_uri('mydata') (no '://' suffix; the function lowercases and strips it for you)","Check the config/env source that supplied the scheme and give it a real value or a non-empty default","Add a caller-side check: if not scheme or not scheme.strip(): raise/skip the registration"],"exampleFix":"// before\nscheme = os.environ.get('OMP_SCHEME', '')\nh = host_uri(scheme, read=read_handler)\n// after\nscheme = os.environ.get('OMP_SCHEME') or 'mydata'\nh = host_uri(scheme, read=read_handler)","handlingStrategy":"validation","validationCode":"def validate_scheme(scheme):\n    if not isinstance(scheme, str) or not scheme.strip():\n        raise ValueError(f\"scheme must be a non-empty string, got {scheme!r}\")\n    return scheme","typeGuard":"def is_valid_scheme(scheme) -> bool:\n    return isinstance(scheme, str) and bool(scheme.strip())","tryCatchPattern":"try:\n    h = host_uri(scheme, read=read_handler)\nexcept ValueError as e:\n    logger.error('host_uri registration failed: %s (scheme=%r)', e, scheme)\n    raise","preventionTips":["Never default scheme to '' — use None and fail explicitly, or a real default","Strip and lowercase at the config-loading layer so bad values are caught early","Add a startup assertion/test that all registered schemes are non-empty"],"tags":["validation","valueerror","host-uri","scheme-registration"],"backgroundTag":"invalid-uri-scheme","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}