Skip to content

[Bug][Relax][ONNX] Max/Min/Sum/Mean importer crashes with "object of type 'NoneType' has no len()" on a valid model whose input has no static shape #20280

Description

@lackjava-creator

Environment

  • TVM version: main @ 48242ec33403f2b6e4fac6e763ca7a683fb9d5df (2026-09-03, reports 0.26.dev0) and release 0.26.0.

  • Build / install: source build for main; venv wheel for 0.26.0

  • OS / Python: Ubuntu 24.04.3 LTS, x86_64, Python 3.10

  • Reference implementation: onnxruntime 1.23.2

  • Target: target-independent — the failure is at import, before any build. Both llvm and cuda unreachable.

  • Pipeline coverage: the failure is at import, before any pipeline runs, so fusion is irrelevant — but reported explicitly anyway. Verified 2026-09-06 on 0.26.0, llvm:

    • get_pipeline("default_build") (no FuseOps/FuseTIR) — fails (TypeError in from_onnx)
    • get_pipeline("zero") (fuses) — fails, identical message
    • forced FuseOps + FuseTIRfails, identical message

Minimal reproducer

Two-node ONNX graph: a Slice with runtime starts/ends, feeding a Max. model.onnx + feed.npz + run.py attached.

import numpy as np, onnx, onnxruntime as ort
from tvm.relax.frontend.onnx import from_onnx
model = onnx.load("model.onnx"); feed = dict(np.load("feed.npz"))
onnx.checker.check_model(model, full_check=True)                    # the model is valid ONNX
print("onnxruntime says:", ort.InferenceSession(model.SerializeToString(),
      providers=["CPUExecutionProvider"]).run(None, feed))
from_onnx(model, shape_dict={k: list(v.shape) for k, v in feed.items()},
          keep_params_in_input=False)                               # <-- TypeError here

Expected vs actual

  • Expected: the model imports. It passes onnx.checker.check_model(..., full_check=True) and onnxruntime executes it and returns the correct tensor.
  • Actual:
TypeError: object of type 'NoneType' has no len()

raised inside the importer, with no indication of which node or which input is at fault.

Root cause (if known)

MultiInputBase._impl_v1 reads inp.ty.shape for every input and passes it to compute_broadcast_shape, which does len(shape_a). An input whose struct-info shape is unknownR.Tensor(dtype=..., ndim=2), which is what R.dynamic_strided_slice produces — has shape is None, so len(None) raises.

Corroborating observations on the same graph and the same build:

  • Add on the same tensor imports fine — the elementwise binary path does not go through this helper.
  • A single-input Max on the same tensor fails differently (Found null pointer node), i.e. the unknown-shape case is unhandled on more than one branch.
  • Max, Min, Sum and Mean all fail identically, which is exactly the set that routes through MultiInputBase.

Never fixed; present on 0.26.0 and main @ 48242ec alike.

Why this is a bug (not tolerance / not undefined behaviour)

The model is valid ONNX, the checker accepts it, and onnxruntime runs it. An importer must either support an input with unknown static shape or reject it with a diagnostic that names the node; len(None) is neither. Unknown-shape struct info is a first-class state in Relax (R.Tensor(dtype=..., ndim=k)), produced by TVM's own R.dynamic_strided_slice, so this is not an exotic input.

Related, not duplicate. Open issue #20175 is the symbolic-dimension failure of the same helper (ValueError: Cannot use and / or / not operator to Expr). Merged PR #20218 (2026-08-30, i.e. before 48242ec) fixed that path — verified: #20175's own reproducer imports successfully on main — but left compute_broadcast_shape's len(shape_a) unguarded against None. Our reproducer still fails on that same commit.

How found

Found by EquiAutomaton (equivalence-graph differential testing against onnxruntime). Depth-0 — two nodes.

Reproducer archive

TVM-C4-reproducer.zip

Triage

  • Needs triage

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triagePRs or issues that need to be investigated by maintainers to find the right assignees to address ittype: bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions