microsoft/qlib · error · TypeError

type(i) = {type(i)}

Error message

type(i) = {type(i)}

What it means

Raised by FileFeatureStorage.__getitem__ (qlib/data/storage/file_storage.py) in its missing-file branch: when the bin file does not exist and the index argument is neither int nor slice, there is nothing sensible to return, so a TypeError reporting the actual type is raised. It parallels the same check in the exists-file branch (error 399) but fires before any file I/O.

Source

Thrown at qlib/data/storage/file_storage.py:353

        with self.uri.open("rb") as fp:
            index = int(np.frombuffer(fp.read(4), dtype="<f")[0])
        return index

    @property
    def end_index(self) -> Union[int, None]:
        if not self.uri.exists():
            return None
        # The next  data appending index point will be  `end_index + 1`
        return self.start_index + len(self) - 1

    def __getitem__(self, i: Union[int, slice]) -> Union[Tuple[int, float], pd.Series]:
        if not self.uri.exists():
            if isinstance(i, int):
                return None, None
            elif isinstance(i, slice):
                return pd.Series(dtype=np.float32)
            else:
                raise TypeError(f"type(i) = {type(i)}")

        storage_start_index = self.start_index
        storage_end_index = self.end_index
        with self.uri.open("rb") as fp:
            if isinstance(i, int):
                if storage_start_index > i:
                    raise IndexError(f"{i}: start index is {storage_start_index}")
                fp.seek(4 * (i - storage_start_index) + 4)
                return i, struct.unpack("f", fp.read(4))[0]
            elif isinstance(i, slice):
                start_index = storage_start_index if i.start is None else i.start
                end_index = storage_end_index if i.stop is None else i.stop - 1
                si = max(start_index, storage_start_index)
                if si > end_index:
                    return pd.Series(dtype=np.float32)
                fp.seek(4 * (si - storage_start_index) + 4)
                # read n bytes
                count = end_index - si + 1

View on GitHub (pinned to 79633dd950)

Solutions

  1. Index with a plain int or a slice only: storage[0], storage[10:20].
  2. Convert numpy scalars with int(n) and use slices or repeated int indexing instead of lists of positions.
  3. Ensure the bin file exists (dump the data) if you expected real values rather than the empty-result path.

Example fix

# before
val = feature_storage[np.int64(5)]  # file missing -> TypeError

# after
val = feature_storage[int(np.int64(5))]
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(i, (int, slice)):
    i = int(i)  # or convert list->slice, float->int

Type guard

def is_storage_index(i) -> bool:
    return isinstance(i, (int, slice)) and not isinstance(i, bool)

Prevention

When it happens

Trigger: feature_storage[n] where the storage bin file is absent and n is a float (1.0), numpy scalar, string, None, or a list of indices. The int and slice cases return (None, None) / empty Series; everything else errors.

Common situations: Code that indexes storages with numpy ints or arrays; None defaults reaching the index expression; probing storage contents for instruments whose data was never dumped.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/8a275e448c4d5593. Report an issue: GitHub.