odysseus-dev/odysseus · error · HTTPException

repo_id is required

Error message

repo_id is required

What it means

HTTP 400 from _validate_serve_model_id() in routes/cookbook_helpers.py when the model identifier is None or an empty string. Serve endpoints require some identifier — HF repo id, Ollama name:tag, or cached local model id — before format-specific validation runs.

Source

Thrown at routes/cookbook_helpers.py:73


def _git_bash_path(path: str) -> str:
    m = re.match(r"^([A-Za-z]):[\\/](.*)$", path)
    if not m:
        return path
    drive, rest = m.groups()
    return f"/{drive.lower()}/{rest.replace(chr(92), '/')}"


def _validate_repo_id(v: str | None) -> str:
    if not v or not _REPO_ID_RE.match(v):
        raise HTTPException(400, "Invalid repo_id — must be <org>/<name> using [A-Za-z0-9._-]")
    return v


def _validate_serve_model_id(v: str | None) -> str:
    if not v:
        raise HTTPException(400, "repo_id is required")
    if _REPO_ID_RE.match(v) or _LOCAL_MODEL_ID_RE.match(v) or _OLLAMA_MODEL_ID_RE.match(v):
        return v
    raise HTTPException(400, "Invalid repo_id — must be <org>/<name>, an Ollama name:tag, or a cached local model id")


def _validate_include(v: str | None) -> str | None:
    if v is None or v == "":
        return None
    if not _INCLUDE_RE.match(v):
        raise HTTPException(400, "Invalid include pattern")
    return v


def _validate_token(v: str | None) -> str | None:
    if v is None or v == "":
        return None
    if not _TOKEN_RE.match(v):
        raise HTTPException(400, "Invalid token characters")

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Include a non-empty repo_id in the request body
  2. Check the exact field name the request model expects (repo_id, not model or model_id)
  3. If serving a raw command with no model, use the endpoint variant that does not require repo_id, or pass a valid model id

Example fix

// before
{"cmd": "vllm serve ..."}  // repo_id missing
// after
{"repo_id": "meta-llama/Meta-Llama-3-8B", "cmd": "vllm serve ..."}
Defensive patterns

Strategy: type-guard

Validate before calling

def has_serve_model_id(payload: dict) -> bool:
    rid = payload.get("repo_id")
    return isinstance(rid, str) and rid.strip() != ""

Type guard

function isServeRequest(p: unknown): p is ServeRequest {
  return (
    typeof p === "object" && p !== null &&
    typeof (p as any).repo_id === "string" &&
    (p as any).repo_id.trim() !== ""
  );
}

Prevention

When it happens

Trigger: POST to a serve endpoint with repo_id omitted from the JSON body, set to null, or set to "".

Common situations: Frontend form submitted before the model field was filled; client code that conditionally omits repo_id when the user picked a custom-command mode; a refactor that renamed the field (model vs repo_id) so the key never arrives.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/2f7f31afc6fcf1d2. Report an issue: GitHub.