calesthio/OpenMontage · error · ValueError

ARK_API_KEY must contain only the API Key body; remove the '

Error message

ARK_API_KEY must contain only the API Key body; remove the 'Bearer ' prefix

What it means

Raised inside `dry_run` when `ARK_API_KEY` starts with the literal prefix 'Bearer ' (case-insensitive): the Ark client adds its own Authorization header formatting, so the env var must contain only the raw API key body. Including the prefix would produce a doubled 'Bearer Bearer ...' header and 401s from Ark. The same condition in `get_status()` merely marks the tool UNAVAILABLE; dry_run surfaces the actionable message instead.

Source

Thrown at tools/video/seedance_ark.py:486

            "task_action": action,
            "status": self.get_status().value,
            "would_execute": False,
            "paid_submission": False,
            "api_contract": {
                "create": f"POST {self.BASE_URL}/contents/generations/tasks",
                "query": (
                    f"GET {self.BASE_URL}/contents/generations/tasks/{{task_id}}"
                ),
                "cancel": (
                    f"DELETE {self.BASE_URL}/contents/generations/tasks/{{task_id}}"
                ),
            },
        }
        try:
            base_url = self._get_base_url()
            api_key = self._get_api_key()
            if api_key and api_key.lower().startswith("bearer "):
                raise ValueError(
                    "ARK_API_KEY must contain only the API Key body; remove "
                    "the 'Bearer ' prefix"
                )
            result["api_contract"] = {
                "create": (f"POST {base_url}/contents/generations/tasks"),
                "query": (f"GET {base_url}/contents/generations/tasks/{{task_id}}"),
                "cancel": (f"DELETE {base_url}/contents/generations/tasks/{{task_id}}"),
            }
            if action in {"query", "cancel"}:
                self._validate_task_id(inputs.get("task_id"))
            else:
                payload = self._build_payload(inputs)
                result.update(
                    {
                        "model": payload["model"],
                        "operation": inputs.get("operation", "text_to_video"),
                        "resolution": payload.get("resolution", "720p"),
                        "ratio": payload.get("ratio", "16:9"),

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Strip the prefix: `export ARK_API_KEY=sk-xxxx` (no 'Bearer ', no quotes needed)
  2. If the key lives in a secrets manager, store only the key body
  3. Quick check: `echo "$ARK_API_KEY" | head -c 7` should not print 'Bearer '

Example fix

# before
export ARK_API_KEY="Bearer 2c0f4f8a-xxxx-xxxx"
# after
export ARK_API_KEY="2c0f4f8a-xxxx-xxxx"
Defensive patterns

Strategy: validation

Validate before calling

api_key = os.environ.get("ARK_API_KEY", "")
if api_key.lower().startswith("bearer "):
    os.environ["ARK_API_KEY"] = api_key[len("bearer "):].strip()
    # or fail loudly:
    # raise ValueError("ARK_API_KEY must not include 'Bearer ' prefix")

Type guard

def is_bare_api_key(key: str) -> bool:
    return bool(key) and not key.lower().startswith("bearer ")

Prevention

When it happens

Trigger: Setting `ARK_API_KEY="Bearer sk-xxxx"` by copy-pasting the full Authorization header value from curl examples or API docs; secrets managers storing the header rather than the key.

Common situations: Copy-paste from Volcengine docs that show `Authorization: Bearer <key>`; users applying OpenAI-style conventions where the header is stored whole; shell history autocompleting a previous header export.

Related errors


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