cayleygraph/cayley · error

can not parse %#v as a literal

Error message

can not parse %#v as a literal

What it means

parseLiteral converts a decoded JSON value into a quad.Value. It accepts plain scalars (string, number, bool) and JSON-LD value objects (maps with @value, optionally @language or @type). When the input matches none of these shapes it cannot be represented as a literal and this error is returned.

Source

Thrown at query/linkedql/registry.go:302

	case float64:
		i := int64(a)
		if a == float64(i) {
			return quad.Int(i), nil
		}
		return quad.Float(a), nil
	case bool:
		return quad.Bool(a), nil
	case map[string]interface{}:
		if val, ok := a["@value"].(string); ok {
			if lang, ok := a["@language"].(string); ok {
				return quad.LangString{Value: quad.String(val), Lang: lang}, nil
			}
			if typ, ok := a["@type"].(string); ok {
				return quad.TypedString{Value: quad.String(val), Type: quad.IRI(typ)}, nil
			}
		}
	}
	return nil, fmt.Errorf("can not parse %#v as a literal", a)
}

func parseValue(a interface{}) (quad.Value, error) {
	identifierString, err := parseIdentifierString(a)
	if err == nil {
		identifier, err := parseIdentifier(identifierString)
		if err == nil {
			return identifier, nil
		}
	}
	lit, err := parseLiteral(a)
	if err == nil {
		return lit, nil
	}
	return nil, fmt.Errorf("can not parse JSON-LD value: %#v", a)
}

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Pass a plain scalar (string, number, boolean) instead of an array or bare map.
  2. For typed/lang values, use the exact JSON-LD shape: {"@value": "...", "@type": "..."} or {"@value": "...", "@language": "en"}.
  3. If the value is a node reference, give it an "@id" so it parses as an identifier instead of reaching parseLiteral.
  4. For lists, expand them into multiple triples/steps rather than a single array literal.

Example fix

// before
{"@type": "http://www.w3.org/2001/XMLSchema#integer"} // missing @value
// after
{"@value": "42", "@type": "http://www.w3.org/2001/XMLSchema#integer"}
Defensive patterns

Strategy: validation

Validate before calling

func isLiteralShape(v interface{}) bool {
  switch v.(type) {
  case string, float64, bool, int, int64:
    return true
  case map[string]interface{}:
    _, ok := v.(map[string]interface{})["@value"]
    return ok
  }
  return false
}

Type guard

func asValueObject(v interface{}) (map[string]interface{}, bool) {
  m, ok := v.(map[string]interface{})
  if !ok { return nil, false }
  _, has := m["@value"]
  return m, has
}

Try / catch

val, err := parseLiteral(v)
if err != nil && strings.Contains(err.Error(), "can not parse") {
  return fmt.Errorf("literal fields accept scalars or {@value,...} objects, got %T", v)
}

Prevention

When it happens

Trigger: parseValue falling through to parseLiteral with arrays, nested maps without @value, or nil — e.g. passing a JSON array as a step's object value, or a value object missing the required "@value" key.

Common situations: Authoring step documents with list-valued properties (RDF has no native list literal); value objects that use "@values" or misspell "@value"; nested node references where a literal was expected; null values in data sources.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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