cayleygraph/cayley · error

must execute a IteratorStep or PathStep

Error message

must execute a IteratorStep or PathStep

What it means

BuildIterator in the linkedql package converts a query step into an iterator, but only steps implementing IteratorStep or PathStep are executable. If the passed step implements neither interface, Cayley returns this error instead of guessing how to build an iterator. It indicates the query step type is not executable as given.

Source

Thrown at query/linkedql/linkedql.go:69

		return nil, err
	}
	ns := voc.Namespaces{}
	step, ok := item.(Step)
	if !ok {
		return nil, errors.New("must execute a Step")
	}
	return BuildIterator(step, s.qs, &ns)
}

// BuildIterator for given Step returns a query.Iterator
func BuildIterator(step Step, qs graph.QuadStore, ns *voc.Namespaces) (query.Iterator, error) {
	switch s := step.(type) {
	case IteratorStep:
		return s.BuildIterator(qs, ns)
	case PathStep:
		return NewValueIteratorFromPathStep(s, qs, ns)
	}
	return nil, errors.New("must execute a IteratorStep or PathStep")
}

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Check that the step's concrete type implements linkedql.IteratorStep (BuildIterator method) or linkedql.PathStep; implement the missing method.
  2. Verify the step was constructed with the correct linkedql step type, not a generic or partial struct.
  3. Update to a version where the step type is executable, or replace the step with a supported equivalent (e.g. linkedql.Entity or a path step).

Example fix

// before
step := myCustomStep{} // implements neither IteratorStep nor PathStep
it, err := linkedql.BuildIterator(ctx, qs, ns, step) // panics-less error
// after
var _ linkedql.IteratorStep = myCustomStep{} // add BuildIterator method first
it, err := linkedql.BuildIterator(ctx, qs, ns, step)
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := step.(linkedql.IteratorStep); !ok {
    if _, ok := step.(linkedql.PathStep); !ok {
        return fmt.Errorf("step %T is not executable", step)
    }
}

Type guard

func isExecutableStep(s query.Step) bool {
    _, it := s.(linkedql.IteratorStep)
    _, ps := s.(linkedql.PathStep)
    return it || ps
}

Try / catch

it, err := linkedql.BuildIterator(ctx, qs, ns, step)
if err != nil {
    if err.Error() == "must execute a IteratorStep or PathStep" {
        return fmt.Errorf("unsupported step type %T", step)
    }
    return err
}

Prevention

When it happens

Trigger: Calling linkedql.BuildIterator (directly or via query.Execute) with a step value that implements neither IteratorStep nor PathStep, e.g. a custom or third-party step, or a step constructed/registered incorrectly.

Common situations: Registering a custom query step without implementing BuildIterator; passing a placeholder or wrapper step; type registration mismatch after decoding a query from JSON so the step unmarshals into a generic type.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/708fd060cb3a9e15. Report an issue: GitHub.