{"record":{"id":"99336eeab4470f67","repo":"unslothai/unsloth","slug":"public-preview-sharing-must-be-true-or-false","errorCode":null,"errorMessage":"Public preview sharing must be true or false.","messagePattern":"Public preview sharing must be true or false\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/preview_sharing_settings.py","lineNumber":50,"sourceCode":"    A *missing* setting defaults to enabled so the feature keeps working as\n    before unless an admin explicitly turns it off. A *read failure* (e.g. a\n    transient SQLite/permission error) fails closed -- this is a kill switch, so\n    an unreadable settings DB must not silently reopen the public surface.\n    \"\"\"\n    try:\n        from storage.studio_db import get_app_setting\n        stored = get_app_setting(PREVIEW_SHARING_SETTING_KEY, None)\n    except Exception:\n        return False\n    parsed = _coerce_bool(stored)\n    return parsed if parsed is not None else DEFAULT_PREVIEW_SHARING_ENABLED\n\n\ndef set_preview_sharing_enabled(value: Any) -> bool:\n    \"\"\"Persist whether public ``/p`` preview links are accepted.\"\"\"\n    parsed = _coerce_bool(value)\n    if parsed is None:\n        raise ValueError(\"Public preview sharing must be true or false.\")\n\n    from storage.studio_db import upsert_app_settings\n\n    upsert_app_settings({PREVIEW_SHARING_SETTING_KEY: parsed})\n    return parsed\n","sourceCodeStart":32,"sourceCodeEnd":56,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/preview_sharing_settings.py#L32-L56","documentation":"Raised by set_preview_sharing_enabled(value) when _coerce_bool(value) returns None — i.e. the value cannot be interpreted as a boolean. The settings API accepts true/false in several forms but rejects ambiguous values; this guards the persisted PREVIEW_SHARING_SETTING_KEY from garbage. Note the read path (get) never raises — it falls back to the default — only the write path validates.","triggerScenarios":"Calling set_preview_sharing_enabled() with values _coerce_bool cannot parse: e.g. 'maybe', 2, [], None (depending on the coercion table), or the string 'yes'/'on' if not in the accepted forms. Typically from a settings API handler passing an unvalidated JSON body field straight through.","commonSituations":"A frontend settings toggle sending a string like 'on'/'off' instead of true/false, a misconfigured API client, or a test sending arbitrary truthy values. Also a stored DB value that round-trips as a non-boolean type.","solutions":["Send an actual JSON boolean (true/false) from the client for this setting.","Validate/coerce at the API boundary before calling set_preview_sharing_enabled: reject anything that is not bool, 'true'/'false', or 0/1.","Return HTTP 400 with the error text so the UI can prompt the user to pick an explicit toggle state."],"exampleFix":"# before\nset_preview_sharing_enabled(request.json.get('enabled'))  # 'on' -> ValueError\n\n# after\nraw = request.json.get('enabled')\nif isinstance(raw, str):\n    raw = raw.strip().lower()\nif raw not in (True, False, 'true', 'false', 1, 0):\n    abort(400, 'Public preview sharing must be true or false.')\nset_preview_sharing_enabled(raw)","handlingStrategy":"type-guard","validationCode":"def to_bool_or_none(v):\n    if isinstance(v, bool): return v\n    if isinstance(v, str) and v.strip().lower() in ('true', 'false'):\n        return v.strip().lower() == 'true'\n    if v in (0, 1): return bool(v)\n    return None\n\nparsed = to_bool_or_none(payload.get('enabled'))\nif parsed is None:\n    abort(400, 'Public preview sharing must be true or false.')\nset_preview_sharing_enabled(parsed)","typeGuard":"def is_valid_preview_sharing_value(v) -> bool:\n    return v is True or v is False or (\n        isinstance(v, str) and v.strip().lower() in ('true', 'false')\n    )","tryCatchPattern":"try:\n    set_preview_sharing_enabled(value)\nexcept ValueError:\n    abort(400, 'Public preview sharing must be true or false.')  # client fix required, no retry","preventionTips":["Send JSON booleans, not strings, for toggle settings.","Validate request bodies against a schema (bool type) before hitting settings setters."],"tags":["validation","settings","boolean-coercion","python"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}