cayleygraph/cayley · error

Unexpected type

Error message

Unexpected type

What it means

The default branch of resolveNames in properties.go:46 throws this bare 'Unexpected type' error when the PropertyPath's concrete type is none of the four supported kinds (PropertyStep, PropertyIRIs, PropertyIRIStrings, PropertyIRI, PropertyIRIString). It means an unknown implementation of the PropertyPathI interface reached the Properties step.

Source

Thrown at query/linkedql/steps/properties.go:46

}

func resolveNames(names *linkedql.PropertyPath) (linkedql.PropertyIRIs, error) {
	if names == nil {
		return nil, fmt.Errorf("Not implemented: should tag all properties")
	}
	switch n := names.PropertyPathI.(type) {
	case linkedql.PropertyStep:
		return nil, fmt.Errorf("Not implemented: should use step to resolve to properties")
	case linkedql.PropertyIRIs:
		return n, nil
	case linkedql.PropertyIRIStrings:
		return n.PropertyIRIs(), nil
	case linkedql.PropertyIRI:
		return linkedql.PropertyIRIs{n}, nil
	case linkedql.PropertyIRIString:
		return linkedql.PropertyIRIs{linkedql.PropertyIRI(n)}, nil
	default:
		return nil, fmt.Errorf("Unexpected type")
	}
}

// BuildPath implements linkedql.PathStep.
func (s *Properties) BuildPath(qs graph.QuadStore, ns *voc.Namespaces) (*path.Path, error) {
	fromPath, err := s.From.BuildPath(qs, ns)
	if err != nil {
		return nil, err
	}
	p := fromPath
	names, err := resolveNames(s.Names)
	if err != nil {
		return nil, err
	}
	for _, n := range names {
		name := quad.IRI(n).FullWith(ns)
		tag := string(name)
		p = p.Save(name, tag)

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Use one of the supported wrappers: PropertyIRIs, PropertyIRIStrings, PropertyIRI, or PropertyIRIString.
  2. Fix unmarshalling so Names decode into the correct linkedql types.
  3. Log the %T of names.PropertyPathI to identify the offending type (wrap the error with type info for debugging).
  4. Extend the switch if a new PropertyPath implementation was added intentionally.

Example fix

// before
Names: []interface{}{"http://example.org/p"} // untyped slice
// after
Names: linkedql.NewPropertyPath(linkedql.PropertyIRIStrings{"http://example.org/p"})
Defensive patterns

Strategy: type-guard

Validate before calling

switch names.PropertyPathI.(type) {
case linkedql.PropertyIRIs, linkedql.PropertyIRIStrings, linkedql.PropertyIRI, linkedql.PropertyIRIString:
  // ok
default:
  return fmt.Errorf("unsupported PropertyPath type %T", names.PropertyPathI)
}

Type guard

func isKnownPropertyPath(v interface{}) bool {
  switch v.(type) {
  case linkedql.PropertyIRIs, linkedql.PropertyIRIStrings, linkedql.PropertyIRI, linkedql.PropertyIRIString, linkedql.PropertyStep:
    return true
  }
  return false
}

Try / catch

p, err := step.BuildPath(qs, ns)
if err != nil {
  if err.Error() == "Unexpected type" {
    return fmt.Errorf("Properties.Names has unsupported type %T", step.Names)
  }
  return err
}

Prevention

When it happens

Trigger: Passing a custom or unmarshalled value as Properties.Names whose underlying type does not match any known linkedql.PropertyPath implementation.

Common situations: Custom JSON unmarshalling that produced an unexpected concrete type (e.g. []interface{} or string instead of the typed wrappers), or third-party code implementing PropertyPathI with a new type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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