cocoindex-io/cocoindex · error · ValueError

Invalid dtype specification: {dtype_spec}

Error message

Invalid dtype specification: {dtype_spec}

What it means

When analyzing an NDArray annotation, extract_ndarray_elem_dtype expects numpy.ndarray[Shape, DType] where DType itself is a parametrized numpy dtype (e.g. np.dtype[np.float32]). If the dtype argument has no type parameters (bare np.dtype, plain np.float64 used directly, or Any), the element dtype cannot be extracted and ValueError is raised.

Source

Thrown at python/cocoindex/_internal/datatype.py:38

try:
    import pydantic

    PYDANTIC_AVAILABLE = True
except ImportError:
    PYDANTIC_AVAILABLE = False

# PEP 695 ``type`` aliases (``typing.TypeAliasType``) only exist on Python 3.12+.
# numpy >= 2.5 defines ``numpy.typing.NDArray`` as one, so we must transparently
# unwrap it to reach the underlying ``numpy.ndarray[...]`` type.
_TypeAliasType = getattr(typing, "TypeAliasType", None)


def extract_ndarray_elem_dtype(ndarray_type: Any) -> Any:
    args = typing.get_args(ndarray_type)
    _, dtype_spec = args
    dtype_args = typing.get_args(dtype_spec)
    if not dtype_args:
        raise ValueError(f"Invalid dtype specification: {dtype_spec}")
    return dtype_args[0]


def is_numpy_number_type(t: type) -> bool:
    return isinstance(t, type) and issubclass(t, (np.integer, np.floating))


def is_namedtuple_type(t: type) -> bool:
    return isinstance(t, type) and issubclass(t, tuple) and hasattr(t, "_fields")


def is_pydantic_model(t: Any) -> bool:
    """Check if a type is a Pydantic model."""
    if not PYDANTIC_AVAILABLE or not isinstance(t, type):
        return False
    try:
        return issubclass(t, pydantic.BaseModel)
    except TypeError:

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Annotate as np.ndarray[Any, np.dtype[np.float32]] (or npt.NDArray[np.float32]) with a parametrized dtype
  2. Use cocoindex's Vector type helper with a concrete scalar type instead of raw ndarray
  3. Check the annotation with typing.get_args before passing it to analysis in custom tooling

Example fix

// before
vec: np.ndarray[Any, np.dtype]  # bare dtype

// after
import numpy.typing as npt
vec: npt.NDArray[np.float32]
Defensive patterns

Strategy: validation

Validate before calling

import typing
def has_parametrized_dtype(t) -> bool:
    args = typing.get_args(t)
    return len(args) == 2 and bool(typing.get_args(args[1]))

Try / catch

try:
    info = coco.analyze_type_info(annotation)
except ValueError as e:
    if "Invalid dtype" in str(e):
        annotation = fix_dtype(annotation)
    else:
        raise

Prevention

When it happens

Trigger: Annotating a field/argument as np.ndarray[Any, np.dtype] (bare dtype), np.ndarray[Any, np.float64] (non-parametrized scalar), or np.ndarray (missing args entirely, giving an unpack failure), then calling analyze_type_info on the annotation.

Common situations: Writing Vector[...] embeddings with sloppy numpy typing; code written for numpy<2.5 where NDArray alias handling differed; using `npt.NDArray` without a dtype parameter.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/a6cc497f514b9c2a. Report an issue: GitHub.