invoke-ai/InvokeAI · error · NameError

%s is not supported

Error message

%s is not supported

What it means

The vendored WatermarkEncoder.set_watermark supports watermark content types 'bits', 'bytes', and 'b16'; any other wmType string raises NameError. This is a vendored legacy API that signals unsupported encoder content types.

Source

Thrown at invokeai/backend/image_util/imwatermark/vendor.py:72

        if bits is None:
            bits = []
        self._watermarks = [int(bit) % 2 for bit in bits]
        self._wmLen = len(self._watermarks)
        self._wmType = "bits"

    def set_watermark(self, wmType="bytes", content=""):
        if wmType == "ipv4":
            self.set_by_ipv4(content)
        elif wmType == "uuid":
            self.set_by_uuid(content)
        elif wmType == "bits":
            self.set_by_bits(content)
        elif wmType == "bytes":
            self.set_by_bytes(content)
        elif wmType == "b16":
            self.set_by_b16(content)
        else:
            raise NameError("%s is not supported" % wmType)

    def get_length(self):
        return self._wmLen

    # @classmethod
    # def loadModel(cls):
    #     RivaWatermark.loadModel()

    def encode(self, cv2Image, method="dwtDct", **configs):
        (r, c, channels) = cv2Image.shape
        if r * c < 256 * 256:
            raise RuntimeError("image too small, should be larger than 256x256")

        if method == "dwtDct":
            embed = EmbedMaxDct(self._watermarks, wmLen=self._wmLen, **configs)
            return embed.encode(cv2Image)
        # elif method == 'dwtDctSvd':
        #     embed = EmbedDwtDctSvd(self._watermarks, wmLen=self._wmLen, **configs)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use one of 'bits', 'bytes', or 'b16' as the watermark type for encoding
  2. Convert your content: e.g. encode text as bytes via set_watermark(content, 'bytes')
  3. For 'ipv4' style watermarks, convert the IP string to bytes and use 'bytes'

Example fix

// before
encoder.set_watermark(wm, "ipv4")
// after
import socket
ip_bytes = socket.inet_aton("192.168.1.1")
encoder.set_watermark(ip_bytes, "bytes")
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_WM_TYPES = {"bits", "bytes", "b16"}
if wm_type not in SUPPORTED_WM_TYPES:
    wm_type = "bytes"
encoder.set_watermark(content, wm_type)

Type guard

def is_encodable_wm_type(t: str) -> bool:
    return t in {"bits", "bytes", "b16"}

Try / catch

try:
    encoder.set_watermark(content, wm_type)
except NameError as e:
    logger.warning("unsupported wmType %s; falling back to bytes", wm_type)
    encoder.set_watermark(str(content).encode(), "bytes")

Prevention

When it happens

Trigger: Constructing WatermarkEncoder with a wm_type other than bits/bytes/b16 (e.g. 'ipv4', 'chars') and then calling add_watermark -> set_watermark.

Common situations: Confusing decoder-only types (like 'ipv4') with encoder types, typos like 'byte', copying decoder constructor args into the encoder.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/21727f62ceab8b0c. Report an issue: GitHub.