666ghj/MiroFish · error · StarHistoryError

generated SVG contains a foreign namespace

Error message

generated SVG contains a foreign namespace

What it means

Raised by `_validate_svg`'s element walk (scripts/star_history.py:1193) when any element in the parsed tree does not belong to the SVG namespace `{http://www.w3.org/2000/svg}` — including namespaced foreign elements (e.g. `xlink:`-only or Adobe/Illustrator namespaces) and non-element nodes with non-string tags (comments/PIs already excluded earlier, but CDATA-style tags surface here). The published chart is a fixed, review-approved element set, so anything foreign is rejected.

Source

Thrown at scripts/star_history.py:1193

        "in": {"SourceGraphic"},
        "in2": {"noise"},
        "xChannelSelector": {"R"},
        "yChannelSelector": {"G"},
        "baseFrequency": {"0.05"},
        "scale": {"5"},
        "fill-opacity": {"0.92"},
        "stroke-linecap": {"round"},
        "stroke-linejoin": {"round"},
        "text-anchor": {"start", "middle", "end"},
        "font-size": {"15", "16", "17", "20"},
        "font-weight": {"700"},
        "transform": {"rotate(-90 22 272)"},
    }
    avatar_count = 0
    watermark_count = 0
    for element in root.iter():
        if not isinstance(element.tag, str) or not element.tag.startswith(svg_namespace):
            raise StarHistoryError("generated SVG contains a foreign namespace")
        local_name = element.tag[len(svg_namespace) :]
        allowed_for_element = allowed_attributes.get(local_name)
        if allowed_for_element is None:
            raise StarHistoryError("generated SVG contains a forbidden element")
        if local_name == "image":
            avatar_attributes = {
                "x": "316",
                "y": "12",
                "width": "22",
                "height": "22",
                "href": OWNER_AVATAR_DATA_URI,
                "clip-path": "url(#clip-circle-title)",
            }
            watermark_attributes = {
                "x": "635",
                "y": "508.333",
                "width": "20",
                "height": "20",

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Regenerate the SVG from `render_svg` rather than editing it with vector tools.
  2. In fork code, only append elements created with the SVG namespace: `ET.SubElement(parent, "{http://www.w3.org/2000/svg}rect")`.
  3. If xlink is needed for `href`, note the validator expects plain `href` attributes — use SVG2-style `href`, not `xlink:href`.
  4. Search the payload for namespace declarations (`xmlns:`) — every one beyond the default SVG namespace will trip this check.

Example fix

# before: default ElementTree namespace -> {http://www.w3.org/2000/svg} mismatch or foreign ns
el = ET.SubElement(root, "rect")  # serializes without svg ns / or wrong ns

# after: create elements explicitly in the SVG namespace
SVG_NS = "http://www.w3.org/2000/svg"
el = ET.SubElement(root, f"{SVG_NS}rect")
Defensive patterns

Strategy: try-catch

Validate before calling

import xml.etree.ElementTree as ET
SVG_NS = "http://www.w3.org/2000/svg"

def only_svg_namespace(payload: bytes) -> bool:
    root = ET.fromstring(payload)
    return all(isinstance(el.tag, str) and el.tag.startswith(f"{{{SVG_NS}}}") for el in root.iter())

Try / catch

try:
    _validate_svg(payload)
except StarHistoryError as exc:
    if "foreign namespace" in str(exc):
        raise ValueError("SVG contains non-SVG-namespace elements; regenerate from render_svg") from exc
    raise

Prevention

When it happens

Trigger: An element whose tag does not start with `{http://www.w3.org/2000/svg}` — commonly `xlink:href` ancestors rewritten as `<ns0:...>` by serializers, editor-added namespaces (Adobe `illustrator:`, Inkscape `sodipodi:`), or fork code appending foreign elements (e.g. `<foreignObject>` with HTML kids, `<iframe>`).

Common situations: Round-tripping the generated SVG through Inkscape/Illustrator and re-validating; forks using ElementTree's `register_namespace` incorrectly so tags serialize as `{ns}tag` with a foreign ns; embedding attempts that inject `<script>` or HTML.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/9c41938c229faad4. Report an issue: GitHub.