mlflow/mlflow · error · HTTPException

custom_path is required when type='custom'.

Error message

custom_path is required when type='custom'.

What it means

When `request.type == "custom"`, `install_skills_endpoint` requires `custom_path` because it has no other way to determine the destination directory. A missing/empty `custom_path` raises HTTP 400 'custom_path is required when type=custom.' The path is later expanduser()'d, so '~' is accepted.

Source

Thrown at mlflow/server/assistant/api.py:783

        project_path = Path(project_location)

    # Skills installation has side effects, so it requires an explicit provider
    # selection instead of using _resolve_provider()'s runtime default.
    provider = _get_selected_provider()
    if provider is None:
        raise HTTPException(
            status_code=412,
            detail="No assistant provider is configured or available.",
        )

    match request.type:
        case "global":
            destination = provider.resolve_skills_path(Path.home())
        case "project":
            destination = provider.resolve_skills_path(project_path)
        case "custom":
            if not request.custom_path:
                raise HTTPException(
                    status_code=400,
                    detail="custom_path is required when type='custom'.",
                )
            destination = Path(request.custom_path).expanduser()

    # Check if skills already exist - skip re-installation
    if destination.exists():
        if current_skills := list_installed_skills(destination):
            return SkillsInstallResponse(
                installed_skills=current_skills, skills_directory=str(destination)
            )

    installed = install_skills(destination)

    return SkillsInstallResponse(installed_skills=installed, skills_directory=str(destination))


@assistant_router.get("/providers/{provider}/models")

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Include a non-empty `custom_path` in the request, e.g. {"type": "custom", "custom_path": "/home/me/project/.claude/skills"}.
  2. Use '~' if you want the server user's home expanded (expanduser is applied server-side).
  3. If you meant a global install, change `type` to "global" and drop `custom_path` entirely.

Example fix

// before
{"type": "custom"}

// after
{"type": "custom", "custom_path": "~/repos/app/.claude/skills"}
Defensive patterns

Strategy: validation

Validate before calling

function validateSkillsInstall(req) {
  if (req.type === 'custom' && !(typeof req.custom_path === 'string' && req.custom_path.trim())) {
    throw new Error("custom_path is required when type='custom'");
  }
}

Type guard

function hasCustomPath(r) { return r.type !== 'custom' || (typeof r.custom_path === 'string' && r.custom_path.trim().length > 0); }

Try / catch

const res = await fetch(`${base}/assistant/skills/install`, {method: 'POST', body: JSON.stringify(req)});
if (res.status === 400) {
  const { detail } = await res.json();
  if (detail.includes('custom_path is required')) req = {...req, custom_path: await promptForPath()};
}

Prevention

When it happens

Trigger: POSTing {"type": "custom"} with `custom_path` absent, null, or empty string; a client that maps a UI 'custom location' toggle without carrying the path field into the payload.

Common situations: Hand-written curl/script payloads; UI form bugs where the custom-path textbox is hidden but type is still 'custom'; copying a global-install payload and only changing `type`.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29). Data as JSON: /api/errors/30f665202f708b76. Report an issue: GitHub.