tinyhumansai/openhuman · critical · ValidationError

Invalid ${paramName}: ${String(value)}. Type must be an inte

Error message

Invalid ${paramName}: ${String(value)}. Type must be an integer or a string.

What it means

Fail-closed security guard in the RPC HTTP bind path (src/core/runtime/builder.rs:692). Binding to a non-loopback host requires an operator-supplied token via the OPENHUMAN_CORE_TOKEN env var (core::auth::CORE_TOKEN_ENV_VAR). The auto-generated {workspace}/core.token file only authenticates local clients — remote clients cannot read a workspace file — so a public bind relying on it would be effectively unauthenticated. The guard prints a [SECURITY] banner to stderr and aborts startup. An in-memory bearer via run_server_embedded_with_ready(rpc_token: Some(_)) also satisfies it.

Source

Thrown at app/src/lib/mcp/validation.ts:46

    if (!Number.isNaN(intValue) && Number.isFinite(intValue)) {
      if (intValue < -(2 ** 63) || intValue > 2 ** 63 - 1) {
        throw new ValidationError(
          `Invalid ${paramName}: ${value}. ID is out of the valid integer range.`
        );
      }
      return intValue;
    }

    if (/^@?[a-zA-Z0-9_]{5,}$/.test(value)) {
      return value.startsWith('@') ? value : `@${value}`;
    }

    throw new ValidationError(
      `Invalid ${paramName}: '${value}'. Must be a valid integer ID or a username string.`
    );
  }

  throw new ValidationError(
    `Invalid ${paramName}: ${String(value)}. Type must be an integer or a string.`
  );
}

/**
 * Validate list of IDs
 */
export function validateIdList(value: unknown, paramName: string): Array<number | string> {
  if (!Array.isArray(value)) {
    throw new ValidationError(`Invalid ${paramName}: must be an array of IDs.`);
  }

  return value.map((item: unknown, index: number) => {
    try {
      return validateId(item, `${paramName}[${index}]`);
    } catch (error) {
      if (error instanceof ValidationError) {
        throw error;

View on GitHub (pinned to a221052e0d)

Solutions

  1. Set OPENHUMAN_CORE_TOKEN to a strong secret on the server (`export OPENHUMAN_CORE_TOKEN=$(openssl rand -hex 32)`) and distribute it to clients via a secret manager
  2. Or bind loopback (127.0.0.1) and expose remotely through an authenticated tunnel/proxy instead
  3. For embedded cores, hand the bearer in-memory: run_server_embedded_with_ready(rpc_token: Some(...)) instead of relying on the file token
  4. Never treat {workspace}/core.token as valid for non-loopback binds — that is exactly what this guard enforces

Example fix

# before (aborts: [SECURITY] Refusing to bind on 0.0.0.0 ...)
OPENHUMAN_CORE_HOST=0.0.0.0 ./target/debug/openhuman-core serve

# after
export OPENHUMAN_CORE_TOKEN="$(openssl rand -hex 32)"
OPENHUMAN_CORE_HOST=0.0.0.0 ./target/debug/openhuman-core serve
Defensive patterns

Strategy: validation

Validate before calling

# bash: pre-flight the token whenever the bind host is non-loopback
is_loopback() { case "$1" in 127.0.0.1|localhost|::1|\[::1\]) return 0;; *) return 1;; esac; }
RPC_HOST="${OPENHUMAN_CORE_HOST:-127.0.0.1}"
if ! is_loopback "$RPC_HOST" && [ -z "${OPENHUMAN_CORE_TOKEN:-}" ]; then
  echo "refusing to start: non-loopback bind ($RPC_HOST) without OPENHUMAN_CORE_TOKEN" >&2; exit 78
fi
exec ./target/debug/openhuman-core serve

Type guard

is_loopback() { case "$1" in 127.0.0.1|localhost|::1|\[::1\]) return 0;; *) return 1;; esac; }

Try / catch

# in the service supervisor / wrapper
if ! out=$(./openhuman-core serve 2>&1); then
  case "$out" in *"Refusing to bind on"*)
    echo "generate a token: export OPENHUMAN_CORE_TOKEN=\"$(openssl rand -hex 32)\" (and give it to clients), or bind 127.0.0.1" >&2
    exit 78 ;;
  esac
  printf '%s\n' "$out" >&2; exit 1
fi

Prevention

When it happens

Trigger: Config or env sets the RPC host to 0.0.0.0 / a LAN IP / a public DNS name (docker -p, LAN device access such as the iOS client, cloud hosting) while OPENHUMAN_CORE_TOKEN is unset; copying a server config to a machine where the env var is not exported; port-forwarding setups that expose the loopback listener.

Common situations: Docker/cloud deployments; LAN connectivity testing for mobile clients; a colleague's working config replicated without the accompanying env var; misreading core.token as sufficient for remote auth.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/0c9df1ab980ae510. Report an issue: GitHub.