calesthio/OpenMontage · error · ValueError

element_id must be positive

Error message

element_id must be positive

What it means

Raised after successful int conversion when the element id is zero or negative. Kling custom-element ids are positive integers, so this guard rejects invalid ids before they reach the API.

Source

Thrown at tools/_kling/elements.py:38

        return []
    if not isinstance(element_list, list):
        raise ValueError("element_list must be a list of element ids or objects")

    normalized: list[dict[str, int]] = []
    for item in element_list:
        raw_id: Any
        if isinstance(item, dict):
            raw_id = item.get("element_id", item.get("id"))
        else:
            raw_id = item
        if raw_id is None:
            raise ValueError("each element_list item must include element_id")
        try:
            element_id = int(raw_id)
        except (TypeError, ValueError) as exc:
            raise ValueError(f"element_id must be an integer-compatible value: {raw_id!r}") from exc
        if element_id <= 0:
            raise ValueError("element_id must be positive")
        normalized.append({"element_id": element_id})
    return normalized


def element_ids(element_list: Any | None) -> list[int]:
    """Return normalized element ids from an element reference list."""

    return [item["element_id"] for item in normalize_element_list(element_list)]


def get_custom_element(element_id: int, client: KlingClient | None = None) -> dict[str, Any]:
    """Fetch one custom element for validation or diagnostics."""

    api = client or KlingClient()
    return api.get(f"/v1/general/advanced-custom-elements/{int(element_id)}")


def list_custom_elements(

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Check where the id originates — an unset variable defaulting to 0 or -1 indicates a missing upstream lookup
  2. Fetch the real id via the element creation/listing API before building element_list
  3. Guard upstream: only append ids that are >= 1

Example fix

// before
element_id = -1  # 'not found' sentinel leaks into the call
refs = normalize_element_list([element_id])

// after
if element_id is None or element_id < 1:
    raise LookupError('element id not resolved')
refs = normalize_element_list([element_id])
Defensive patterns

Strategy: validation

Validate before calling

def is_positive_element_id(value) -> bool:
    try:
        return int(value) > 0
    except (TypeError, ValueError):
        return False

Type guard

def resolved_element_id(value) -> int | None:
    try:
        eid = int(value)
    except (TypeError, ValueError):
        return None
    return eid if eid > 0 else None

Try / catch

try:
    refs = normalize_element_list(items)
except ValueError as e:
    if 'positive' in str(e):
        raise ValueError(f'unresolved element id (0 or negative): check upstream lookup') from e
    raise

Prevention

When it happens

Trigger: Passing 0 as a placeholder/default id; negative ids from subtraction bugs or default -1 sentinels; numeric strings like '-5' or '0'.

Common situations: Uninitialized id variables (0) forwarded to the call; code using -1 as 'not found' sentinel and passing it through; off-by-one index math producing 0.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/0d48aae0f7352c8f. Report an issue: GitHub.