{"record":{"id":"3aa85bf7bdf438c7","repo":"calesthio/OpenMontage","slug":"safety-identifier-must-be-at-most-64-characters","errorCode":null,"errorMessage":"safety_identifier must be at most 64 characters","messagePattern":"safety_identifier must be at most 64 characters","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/video/seedance_ark.py","lineNumber":1219,"sourceCode":"                    f\"{label} must be a public/signed URL or asset:// ID; \"\n                    \"Ark does not document video Base64 or local paths\"\n                )\n\n    def _validate_optional_parameters(self, payload: dict[str, Any]) -> None:\n        callback = payload.get(\"callback_url\")\n        if callback is not None and not str(callback).startswith(\n            (\"https://\", \"http://\")\n        ):\n            raise ValueError(\"callback_url must be an http(s) URL\")\n        expires = payload.get(\"execution_expires_after\")\n        if expires is not None and not 3600 <= int(expires) <= 259200:\n            raise ValueError(\"execution_expires_after must be between 3600 and 259200\")\n        priority = payload.get(\"priority\")\n        if priority is not None and not 0 <= int(priority) <= 9:\n            raise ValueError(\"priority must be between 0 and 9\")\n        safety = payload.get(\"safety_identifier\")\n        if safety is not None and len(str(safety)) > 64:\n            raise ValueError(\"safety_identifier must be at most 64 characters\")\n\n    def _validate_request_size(self, payload: dict[str, Any]) -> None:\n        # Base64 dominates request size; summing encoded media is a conservative\n        # lower-cost check that avoids building a second complete JSON string.\n        encoded_bytes = 0\n        for item in payload[\"content\"]:\n            media = (\n                item.get(\"image_url\")\n                or item.get(\"audio_url\")\n                or item.get(\"video_url\")\n                or {}\n            )\n            url = str(media.get(\"url\", \"\"))\n            if url.startswith(\"data:\"):\n                encoded_bytes += len(url.encode(\"ascii\"))\n        if encoded_bytes >= self.MAX_REQUEST_BYTES:\n            raise ValueError(\"Ark request body must be smaller than 64 MB\")\n","sourceCodeStart":1201,"sourceCodeEnd":1237,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/seedance_ark.py#L1201-L1237","documentation":"Raised by SeedanceArkVideo._validate_optional_parameters when the optional 'safety_identifier' string exceeds 64 characters. Ark uses safety_identifier to attribute generations to an end user for abuse tracking, and enforces a 64-character ceiling. The check is client-side, so it fires before any request is sent.","triggerScenarios":"Passing safety_identifier as a long free-form label, a concatenated user+session string, a UUID with a namespace prefix, or a JSON blob instead of a short user identifier.","commonSituations":"Developers embedding emails, composite keys, or serialized metadata into safety_identifier; or hashing schemes that emit long hex digests.","solutions":["Pass a short stable identifier such as a user id, truncated hash, or UUID (36 chars).","If you need longer attribution data, hash it first (e.g. sha256 hexdigest truncated to 64) or store the mapping server-side.","Omit the key if you do not need per-user attribution."],"exampleFix":"# before\ninputs = {\"safety_identifier\": f\"tenant={tenant}:user={email}:session={sid}\"}\n\n# after\nimport hashlib\ninputs = {\"safety_identifier\": hashlib.sha256(email.encode()).hexdigest()[:32]}","handlingStrategy":"validation","validationCode":"sid = inputs.get(\"safety_identifier\")\nif sid is not None and len(str(sid)) > 64:\n    import hashlib\n    inputs[\"safety_identifier\"] = hashlib.sha256(str(sid).encode()).hexdigest()[:32]","typeGuard":"def is_valid_safety_identifier(v) -> bool:\n    return v is None or len(str(v)) <= 64","tryCatchPattern":null,"preventionTips":["Pass opaque short ids (user id / UUID) as safety_identifier, never composite strings.","Hash long identifiers before sending."],"tags":["validation","seedance","ark","parameters"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}