Skip to content

# pyshacl Bug Report: Property Paths in SPARQL Constraints Incorrectly Flagged as VALUES Clause #301

@nossrednaanna

Description

@nossrednaanna

Environment

  • pyshacl version: 0.30.1
  • Python version: 3.13.7
  • OS: macOS

Summary

SPARQL constraints using property path syntax (e.g., rdf:rest/rdf:first or rdf:rest*) are incorrectly rejected with the error "A SPARQL Constraint must not contain a VALUES clause", even though no VALUES clause is present in the query. This prevents valid SHACL shapes from executing.

Expected Behavior

SPARQL constraints should accept standard SPARQL property path syntax and execute the constraint queries to validate RDF data.

Actual Behavior

Any SPARQL constraint containing property path syntax triggers a ValidationFailure with the message:

A SPARQL Constraint must not contain a VALUES clause.

The constraint is not executed, causing validation to silently pass even when data violates the constraint.

Minimal Reproducible Example

Test Data

@prefix ex: <http://example.org/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:myVariable
    a ex:Variable, owl:NamedIndividual ;
    ex:name "test_variable" ;
    ex:datatype xsd:integer ;
    ex:allowedValues ( "1"^^xsd:integer "test"^^xsd:string "5"^^xsd:integer) .

SHACL Shape (triggers bug)

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ex: <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

ex:TestShape
    a sh:NodeShape ;
    sh:targetClass ex:Variable ;
    sh:sparql [
        a sh:SPARQLConstraint ;
        sh:message "Test constraint" ;
        sh:select '''
            PREFIX ex: <http://example.org/>
            PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
            SELECT $this WHERE {
                $this ex:allowedValues ?list .
                ?list rdf:rest/rdf:first ?val .
            }
        ''' ;
    ] .

Python Code

from rdflib import Graph
from pyshacl import validate

state_data = """..."""  # Insert test data from above
simple_test_shacl = """..."""  # Insert shape from above

sd = Graph().parse(data=state_data, format="turtle")
s = Graph().parse(data=simple_test_shacl, format="turtle")

conforms, report, message = validate(sd, shacl_graph=s, advanced=True, debug=False)
print(f"Conforms: {conforms}")
print(f"Report type: {type(report)}")
print(f"Message: {message}")

Output

Conforms: False
Report type: <class 'pyshacl.errors.ValidationFailure'>
Message: Validation Failure - A SPARQL Constraint must not contain a VALUES clause.

Analysis

The error occurs with:

  • Property path chains: ?s rdf:rest/rdf:first ?o
  • Kleene star paths: ?s rdf:rest*/rdf:first ?o
  • Property paths in UNION clauses

The SPARQL query contains NO VALUES clause - this appears to be a false positive in pyshacl's constraint parser.

Verification

Running the exact same SPARQL query directly on the graph works correctly:

query = """
PREFIX ex: <http://example.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?var ?list ?val WHERE {
    ?var ex:allowedValues ?list .
    ?list rdf:rest/rdf:first ?val .
}
"""
results = sd.query(query)
for row in results:
    print(row)  # Returns correct results

This proves the SPARQL syntax is valid and executable - the issue is in pyshacl's constraint validation logic.

Workaround

Using explicit triple patterns instead of property paths works:

SELECT $this WHERE {
    $this ex:allowedValues ?list .
    ?list rdf:rest ?rest1 .
    ?rest1 rdf:first ?val .
}

However, this is very verbose and defeats the purpose of property path syntax, especially for complex paths or paths requiring Kleene star (*).

Impact

  • Cannot use standard SPARQL property path syntax in SHACL constraints
  • Validation silently succeeds when it should fail (serious correctness issue)
  • Forces verbose, error-prone workarounds for RDF list traversal
  • Limits SHACL expressiveness significantly

Additional Context

This issue particularly affects validation of RDF lists (common pattern using rdf:first/rdf:rest), where property paths are the natural and recommended approach in SPARQL.

The W3C SHACL specification does prohibit VALUES clauses in SPARQL constraints (section 3.6.1), but property paths are completely separate syntax and should be allowed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions