Skip to content

SHACL-JS Functions Not Executing Correctly in pyshacl #302

@Myasir92

Description

@Myasir92

JavaScript constraint functions defined in external .js files are not executing the actual code in the file. The validation behaves as if a different version of the function is being used, suggesting a caching issue or file loading problem.

Environment

  • pyshacl version: 0.30.1
  • pyduktape2 version: 0.5.0
  • Python version: 3.10.12
  • OS: WSL Ubuntu on Windows
  • rdflib version: 7.4.0

Expected Behavior

When a SHACL-JS constraint references an external JavaScript file, the current content of that file should be loaded and executed during validation.

Actual Behavior

The validation executes a different version of the JavaScript function than what is currently in the file, suggesting either:

  1. The JavaScript file is cached and not reloaded
  2. The wrong file is being loaded

Minimal Reproduction Case

1. Setup Files

data.ttl:

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

ex:Item1 a ex:Product ;
    ex:name "Test Name" .

shape.ttl:

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ex: <http://example.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:ProductNameShape
    a sh:NodeShape ;
    sh:targetClass ex:Product ;
    sh:property [
        sh:path ex:name ;
        sh:js [
            a sh:JSConstraint ;
            sh:message "Name must be between 3 and 100 characters" ;
            sh:jsFunctionName "validateName" ;
            sh:jsLibrary [
                sh:jsLibraryURL "validate.js"^^xsd:anyURI ;
            ] ;
        ] ;
    ] .

validate.js:

function validateName($value) {
    var name = $value;
    var length = name.length;
    // Return true if length is between 3 and 100
    return length >= 3 && length <= 100;
}

2. Run Validation

from pyshacl import validate

r = validate(
    'data.ttl',
    shacl_graph='shape.ttl',
    js=True,
    advanced=True
)

conforms, results_graph, results_text = r
print(f"Conforms: {conforms}")
print(results_text)

3. Observe the Problem

Test Case: "Test Name" = 9 characters

Expected Result:

  • Since 9 is between 3 and 100, the function should return true
  • Validation should PASS (conforms = True)

Actual Result:

Conforms: False
Results (1):
Constraint Violation in JSConstraint
    Focus Node: ex:Item1
    Value Node: Literal("Test Name")
    Message: Name must be between 3 and 100 characters

The validation FAILS, meaning the JavaScript function returned false, but according to the code return length >= 3 && length <= 100, it should return true for 9 characters.

Additional Evidence

Test with Multiple Items

data.ttl with 3 items:

@prefix ex: <http://example.org/> .

ex:Item1 a ex:Product ;
    ex:name "Hello World" .          # 11 characters

ex:Item2 a ex:Product ;
    ex:name "X" .                     # 1 character

ex:Item3 a ex:Product ;
    ex:name "Sample Product" .        # 14 characters

Current JavaScript function:

function validateName($value) {
    var name = $value;
    var length = name.length;
    return length >= 3 && length <= 100;  // Accept 3-100 chars
}

Expected Results:

  • "X" (1 char) → FAIL (< 3)
  • "Hello World" (11 chars) → PASS (3 ≤ 11 ≤ 100)
  • "Sample Product" (14 chars) → PASS (3 ≤ 14 ≤ 100)
  • Total: 1 failure

Actual Results:

Validation FAILED
Total errors: 3

All 3 items fail validation

This confirms the JavaScript is not executing the current code. It appears to be executing an older version where the condition was different (possibly >= 90 && <= 100).

Impact

This makes SHACL-JS unreliable for production use because:

  • Changes to JavaScript validation logic don't take effect
  • No way to debug or verify which version of the code is executing
  • Unpredictable validation behavior
  • Cannot trust that the JavaScript function in the file is what's being executed

References:

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