v8r icon indicating copy to clipboard operation
v8r copied to clipboard

schema with key or id "https://json-schema.org/draft/2019-09/schema" already exists

Open bdovaz opened this issue 3 years ago • 4 comments

Trying to lint a docker-compose.yml file:

 Processing docker-compose.yml
ℹ Cache miss: calling https://json.schemastore.org/schema-catalog.json
ℹ Searching for schema in my-catalog.json ...
ℹ Found schema in my-catalog.json ...
ℹ Cache miss: calling https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json
ℹ Validating docker-compose.yml against schema from https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json ...
ℹ Cache miss: calling http://json-schema.org/draft/2019-09/schema
✖ schema with key or id "https://json-schema.org/draft/2019-09/schema" already exists

I get exit code 1 because of this.

bdovaz avatar Oct 18 '22 21:10 bdovaz

As noted in https://github.com/chris48s/v8r#faq v8r is not a validator in itself. Its a convenience layer between schemastore and ajv.

This is an error which is thrown by Ajv when trying to load the schema.

Although I do try to do what I can within this tool to maximise compatibility, there are some non-zero number of schemas on schemastore which don't work due to either an issue with the schema, bugs in ajv, or differing approaches to ambiguities in the schema drafts. I think in this case, there are some issues with the schema at https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json but some validation libraries may be a little more lenient than AJV in parsing it. The schemas linked from the schemastore catalog do tend to vary quite widely in quality and some are more useful than others. Having a quick look at it, it looks to me like https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json may actually be implementing an earlier draft than draft/2019-09 but I've not really dug into it.

chris48s avatar Oct 19 '22 20:10 chris48s

But then what do you want to tell me that has no solution? If I can't use a schema as famous and used as docker-compose, I can't use this validator...

bdovaz avatar Oct 20 '22 15:10 bdovaz

Not as such.

In its current form, the schema at https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json is in itself invalid according to at least some subset of json schema parsers. This is not unique to v8r. For example, if you use ajv-cli instead it will also tell you this schema is invalid:

$ curl "https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json" --output compose-spec.json

...

$ npx ajv-cli@latest compile -s compose-spec.json 
schema compose-spec.json is invalid

That is not to say this situation is unfixable. For example, with the following modifications that schema would be usable:

diff --git a/schema/compose-spec.json b/schema/compose-spec.json
index d744d3d..4da419f 100644
--- a/schema/compose-spec.json
+++ b/schema/compose-spec.json
@@ -1,6 +1,6 @@
 {
-  "$schema": "http://json-schema.org/draft/2019-09/schema#",
-  "id": "compose_spec.json",
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "$id": "compose_spec.json",
   "type": "object",
   "title": "Compose Specification",
   "description": "The Compose file is a YAML file defining a multi-containers based application.",
@@ -17,7 +17,7 @@
     },
 
     "services": {
-      "id": "#/properties/services",
+      "$id": "#/properties/services",
       "type": "object",
       "patternProperties": {
         "^[a-zA-Z0-9._-]+$": {
@@ -28,7 +28,7 @@
     },
 
     "networks": {
-      "id": "#/properties/networks",
+      "$id": "#/properties/networks",
       "type": "object",
       "patternProperties": {
         "^[a-zA-Z0-9._-]+$": {
@@ -38,7 +38,7 @@
     },
 
     "volumes": {
-      "id": "#/properties/volumes",
+      "$id": "#/properties/volumes",
       "type": "object",
       "patternProperties": {
         "^[a-zA-Z0-9._-]+$": {
@@ -49,7 +49,7 @@
     },
 
     "secrets": {
-      "id": "#/properties/secrets",
+      "$id": "#/properties/secrets",
       "type": "object",
       "patternProperties": {
         "^[a-zA-Z0-9._-]+$": {
@@ -60,7 +60,7 @@
     },
 
     "configs": {
-      "id": "#/properties/configs",
+      "$id": "#/properties/configs",
       "type": "object",
       "patternProperties": {
         "^[a-zA-Z0-9._-]+$": {
@@ -77,7 +77,7 @@
   "definitions": {
 
     "service": {
-      "id": "#/definitions/service",
+      "$id": "#/definitions/service",
       "type": "object",
 
       "properties": {
@@ -431,7 +431,7 @@
     },
 
     "healthcheck": {
-      "id": "#/definitions/healthcheck",
+      "$id": "#/definitions/healthcheck",
       "type": "object",
       "properties": {
         "disable": {"type": "boolean"},
@@ -450,7 +450,7 @@
       "patternProperties": {"^x-": {}}
     },
     "deployment": {
-      "id": "#/definitions/deployment",
+      "$id": "#/definitions/deployment",
       "type": ["object", "null"],
       "properties": {
         "mode": {"type": "string"},
@@ -552,7 +552,7 @@
     },
 
     "generic_resources": {
-      "id": "#/definitions/generic_resources",
+      "$id": "#/definitions/generic_resources",
       "type": "array",
       "items": {
         "type": "object",
@@ -573,7 +573,7 @@
     },
 
     "devices": {
-      "id": "#/definitions/devices",
+      "$id": "#/definitions/devices",
       "type": "array",
       "items": {
         "type": "object",
@@ -590,7 +590,7 @@
     },
 
     "network": {
-      "id": "#/definitions/network",
+      "$id": "#/definitions/network",
       "type": ["object", "null"],
       "properties": {
         "name": {"type": "string"},
@@ -653,7 +653,7 @@
     },
 
     "volume": {
-      "id": "#/definitions/volume",
+      "$id": "#/definitions/volume",
       "type": ["object", "null"],
       "properties": {
         "name": {"type": "string"},
@@ -682,7 +682,7 @@
     },
 
     "secret": {
-      "id": "#/definitions/secret",
+      "$id": "#/definitions/secret",
       "type": "object",
       "properties": {
         "name": {"type": "string"},
@@ -709,7 +709,7 @@
     },
 
     "config": {
-      "id": "#/definitions/config",
+      "$id": "#/definitions/config",
       "type": "object",
       "properties": {
         "name": {"type": "string"},
@@ -798,7 +798,7 @@
 
     "constraints": {
       "service": {
-        "id": "#/definitions/constraints/service",
+        "$id": "#/definitions/constraints/service",
         "anyOf": [
           {"required": ["build"]},
           {"required": ["image"]}

although I don't know if that is exactly the original author's intent or not. It is one possible solution. What I'm getting at is: I'm sure this is fixable by submitting a PR to https://github.com/compose-spec/compose-spec fixing the schema upstream, but it probably requires some input from the authors.

If your requirement is strictly "I need to be able to validate a file against the schema at https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json with zero modifications to the schema", you are right. You can't use this tool, or ajv-cli, or probably other validation tools. You may be able to find a tool which is a bit less strict about what it will accept. Schemasafe could be worth a look for that use-case.

chris48s avatar Oct 24 '22 19:10 chris48s

~~Bunch of info repeated~~

I managed to skip all of chris' comment, huh?

Removing comment, sorry for necrobumping.

Abrifq avatar Sep 25 '23 20:09 Abrifq