diff --git a/cdevents-sdk/Cargo.toml b/cdevents-sdk/Cargo.toml
index 1c71fb0..409c9c2 100644
--- a/cdevents-sdk/Cargo.toml
+++ b/cdevents-sdk/Cargo.toml
@@ -24,6 +24,7 @@ assert-json-diff = "2.0"
 boon = "0.5"
 glob = "0.3"
 proptest = "1"
+regex = "1.10"
 rstest = "0.19"
 
 [features]
diff --git a/cdevents-sdk/src/generated/mod.rs b/cdevents-sdk/src/generated/mod.rs
index cf13909..a9ad04e 100644
--- a/cdevents-sdk/src/generated/mod.rs
+++ b/cdevents-sdk/src/generated/mod.rs
@@ -177,7 +177,46 @@ pub mod spec_0_3_0 {
     pub use super::testsuiterun_queued_0_1_0 as testsuiterun_queued;
     pub use super::testsuiterun_started_0_1_0 as testsuiterun_started;
 }
-pub mod spec_0_4_0 {
+pub mod spec_0_4_0_draft {
+    pub use super::artifact_signed_0_1_0 as artifact_signed;
+    pub use super::branch_created_0_1_2 as branch_created;
+    pub use super::branch_deleted_0_1_2 as branch_deleted;
+    pub use super::build_finished_0_1_1 as build_finished;
+    pub use super::build_queued_0_1_1 as build_queued;
+    pub use super::build_started_0_1_1 as build_started;
+    pub use super::change_abandoned_0_1_2 as change_abandoned;
+    pub use super::change_created_0_2_0 as change_created;
+    pub use super::change_merged_0_1_2 as change_merged;
+    pub use super::change_reviewed_0_1_2 as change_reviewed;
+    pub use super::change_updated_0_1_2 as change_updated;
+    pub use super::environment_created_0_1_1 as environment_created;
+    pub use super::environment_deleted_0_1_1 as environment_deleted;
+    pub use super::environment_modified_0_1_1 as environment_modified;
+    pub use super::incident_detected_0_1_0 as incident_detected;
+    pub use super::incident_reported_0_1_0 as incident_reported;
+    pub use super::incident_resolved_0_1_0 as incident_resolved;
+    pub use super::pipelinerun_finished_0_1_1 as pipelinerun_finished;
+    pub use super::pipelinerun_queued_0_1_1 as pipelinerun_queued;
+    pub use super::pipelinerun_started_0_1_1 as pipelinerun_started;
+    pub use super::repository_created_0_1_1 as repository_created;
+    pub use super::repository_deleted_0_1_1 as repository_deleted;
+    pub use super::repository_modified_0_1_1 as repository_modified;
+    pub use super::service_deployed_0_1_1 as service_deployed;
+    pub use super::service_published_0_1_1 as service_published;
+    pub use super::service_removed_0_1_1 as service_removed;
+    pub use super::service_rolledback_0_1_1 as service_rolledback;
+    pub use super::service_upgraded_0_1_1 as service_upgraded;
+    pub use super::taskrun_finished_0_1_1 as taskrun_finished;
+    pub use super::taskrun_started_0_1_1 as taskrun_started;
+    pub use super::testcaserun_finished_0_1_0 as testcaserun_finished;
+    pub use super::testcaserun_queued_0_1_0 as testcaserun_queued;
+    pub use super::testcaserun_started_0_1_0 as testcaserun_started;
+    pub use super::testoutput_published_0_1_0 as testoutput_published;
+    pub use super::testsuiterun_finished_0_1_0 as testsuiterun_finished;
+    pub use super::testsuiterun_queued_0_1_0 as testsuiterun_queued;
+    pub use super::testsuiterun_started_0_1_0 as testsuiterun_started;
+}
+pub mod spec_0_4_1 {
     pub use super::artifact_deleted_0_1_0 as artifact_deleted;
     pub use super::artifact_downloaded_0_1_0 as artifact_downloaded;
     pub use super::artifact_packaged_0_2_0 as artifact_packaged;
@@ -224,45 +263,6 @@ pub mod spec_0_4_0 {
     pub use super::ticket_created_0_1_0 as ticket_created;
     pub use super::ticket_updated_0_1_0 as ticket_updated;
 }
-pub mod spec_0_4_0_draft {
-    pub use super::artifact_signed_0_1_0 as artifact_signed;
-    pub use super::branch_created_0_1_2 as branch_created;
-    pub use super::branch_deleted_0_1_2 as branch_deleted;
-    pub use super::build_finished_0_1_1 as build_finished;
-    pub use super::build_queued_0_1_1 as build_queued;
-    pub use super::build_started_0_1_1 as build_started;
-    pub use super::change_abandoned_0_1_2 as change_abandoned;
-    pub use super::change_created_0_2_0 as change_created;
-    pub use super::change_merged_0_1_2 as change_merged;
-    pub use super::change_reviewed_0_1_2 as change_reviewed;
-    pub use super::change_updated_0_1_2 as change_updated;
-    pub use super::environment_created_0_1_1 as environment_created;
-    pub use super::environment_deleted_0_1_1 as environment_deleted;
-    pub use super::environment_modified_0_1_1 as environment_modified;
-    pub use super::incident_detected_0_1_0 as incident_detected;
-    pub use super::incident_reported_0_1_0 as incident_reported;
-    pub use super::incident_resolved_0_1_0 as incident_resolved;
-    pub use super::pipelinerun_finished_0_1_1 as pipelinerun_finished;
-    pub use super::pipelinerun_queued_0_1_1 as pipelinerun_queued;
-    pub use super::pipelinerun_started_0_1_1 as pipelinerun_started;
-    pub use super::repository_created_0_1_1 as repository_created;
-    pub use super::repository_deleted_0_1_1 as repository_deleted;
-    pub use super::repository_modified_0_1_1 as repository_modified;
-    pub use super::service_deployed_0_1_1 as service_deployed;
-    pub use super::service_published_0_1_1 as service_published;
-    pub use super::service_removed_0_1_1 as service_removed;
-    pub use super::service_rolledback_0_1_1 as service_rolledback;
-    pub use super::service_upgraded_0_1_1 as service_upgraded;
-    pub use super::taskrun_finished_0_1_1 as taskrun_finished;
-    pub use super::taskrun_started_0_1_1 as taskrun_started;
-    pub use super::testcaserun_finished_0_1_0 as testcaserun_finished;
-    pub use super::testcaserun_queued_0_1_0 as testcaserun_queued;
-    pub use super::testcaserun_started_0_1_0 as testcaserun_started;
-    pub use super::testoutput_published_0_1_0 as testoutput_published;
-    pub use super::testsuiterun_finished_0_1_0 as testsuiterun_finished;
-    pub use super::testsuiterun_queued_0_1_0 as testsuiterun_queued;
-    pub use super::testsuiterun_started_0_1_0 as testsuiterun_started;
-}
 
 pub const ARTIFACT_DELETED_0_1_0: &str = "dev.cdevents.artifact.deleted.0.1.0";
 pub const ARTIFACT_DOWNLOADED_0_1_0: &str = "dev.cdevents.artifact.downloaded.0.1.0";
diff --git a/cdevents-sdk/src/generated/ticket_closed_0_1_0.rs b/cdevents-sdk/src/generated/ticket_closed_0_1_0.rs
index 8089c51..cf91071 100644
--- a/cdevents-sdk/src/generated/ticket_closed_0_1_0.rs
+++ b/cdevents-sdk/src/generated/ticket_closed_0_1_0.rs
@@ -19,13 +19,13 @@ pub struct Content {
     #[serde(rename = "milestone", default, skip_serializing_if = "Option::is_none",)]
     pub milestone: Option<String>,
     #[serde(rename = "priority", default, skip_serializing_if = "Option::is_none",)]
-    pub priority: Option<String>,
+    pub priority: Option<crate::NonEmptyString>,
     #[serde(rename = "resolution",)]
-    pub resolution: String,
+    pub resolution: crate::NonEmptyString,
     #[serde(rename = "summary", default, skip_serializing_if = "Option::is_none",)]
     pub summary: Option<String>,
     #[serde(rename = "ticketType", default, skip_serializing_if = "Option::is_none",)]
-    pub ticket_type: Option<String>,
+    pub ticket_type: Option<crate::NonEmptyString>,
     #[serde(rename = "updatedBy", default, skip_serializing_if = "Option::is_none",)]
     pub updated_by: Option<String>,
     #[serde(rename = "uri",)]
diff --git a/cdevents-sdk/src/generated/ticket_created_0_1_0.rs b/cdevents-sdk/src/generated/ticket_created_0_1_0.rs
index 18d8abd..9455f02 100644
--- a/cdevents-sdk/src/generated/ticket_created_0_1_0.rs
+++ b/cdevents-sdk/src/generated/ticket_created_0_1_0.rs
@@ -19,11 +19,11 @@ pub struct Content {
     #[serde(rename = "milestone", default, skip_serializing_if = "Option::is_none",)]
     pub milestone: Option<String>,
     #[serde(rename = "priority", default, skip_serializing_if = "Option::is_none",)]
-    pub priority: Option<String>,
+    pub priority: Option<crate::NonEmptyString>,
     #[serde(rename = "summary",)]
     pub summary: String,
     #[serde(rename = "ticketType", default, skip_serializing_if = "Option::is_none",)]
-    pub ticket_type: Option<String>,
+    pub ticket_type: Option<crate::NonEmptyString>,
     #[serde(rename = "uri",)]
     pub uri: crate::UriReference,
 }
diff --git a/cdevents-sdk/src/generated/ticket_updated_0_1_0.rs b/cdevents-sdk/src/generated/ticket_updated_0_1_0.rs
index 3cb4b37..6518119 100644
--- a/cdevents-sdk/src/generated/ticket_updated_0_1_0.rs
+++ b/cdevents-sdk/src/generated/ticket_updated_0_1_0.rs
@@ -19,11 +19,11 @@ pub struct Content {
     #[serde(rename = "milestone", default, skip_serializing_if = "Option::is_none",)]
     pub milestone: Option<String>,
     #[serde(rename = "priority", default, skip_serializing_if = "Option::is_none",)]
-    pub priority: Option<String>,
+    pub priority: Option<crate::NonEmptyString>,
     #[serde(rename = "summary", default, skip_serializing_if = "Option::is_none",)]
     pub summary: Option<String>,
     #[serde(rename = "ticketType", default, skip_serializing_if = "Option::is_none",)]
-    pub ticket_type: Option<String>,
+    pub ticket_type: Option<crate::NonEmptyString>,
     #[serde(rename = "updatedBy", default, skip_serializing_if = "Option::is_none",)]
     pub updated_by: Option<String>,
     #[serde(rename = "uri",)]
diff --git a/cdevents-sdk/tests/specs.rs b/cdevents-sdk/tests/specs.rs
index 50bfb7c..a85f156 100644
--- a/cdevents-sdk/tests/specs.rs
+++ b/cdevents-sdk/tests/specs.rs
@@ -55,7 +55,14 @@ struct HackUrlLoader;
 
 impl UrlLoader for HackUrlLoader {
     fn load(&self, url: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
-        if url.starts_with("https://cdevents.dev/schema/links/") {
+        let re = regex::Regex::new(r"https://cdevents.dev/(?<version>\d+\.\d+)\.\d+/schema/(?<path>.*)")?;
+        if let Some(caps) = re.captures(url) {
+            let path = format!("../cdevents-specs/spec-v{}/schemas/{}.json", &caps["version"], &caps["path"]);
+            let jsonschema: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
+            Ok(jsonschema)
+        } else if url.starts_with("https://cdevents.dev/schema/links/") {
+            // HACK to fix a bug in specs 0.4.0
+            // [Link's ref path needs an update for all the event schemas · Issue #211 · cdevents/spec](https://github.com/cdevents/spec/issues/211)
             let path = url.replace("https://cdevents.dev/schema", "../cdevents-specs/spec-v0.4/schemas/");
             let jsonschema: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
             Ok(jsonschema)
@@ -73,7 +80,7 @@ fn events_schemas() -> &'static EventsSchemas {
 #[rstest]
 fn can_serde_example(#[files("../cdevents-specs/spec-*/examples/*.json")] path: PathBuf) {
     let example_txt = fs::read_to_string(path).expect("to read file as string");
-    //HACK uri are stored ad http::Uri, they are "normalized" when serialized, so prenormalization to avoid failure like
+    // HACK uri are stored ad http::Uri, they are "normalized" when serialized, so prenormalization to avoid failure like
     // json atoms at path ".subject.content.repository.source" are not equal:
     //     lhs:
     //         "https://example.org"
diff --git a/cdevents-specs/spec-v0.4 b/cdevents-specs/spec-v0.4
index b462f84..f95df21 160000
--- a/cdevents-specs/spec-v0.4
+++ b/cdevents-specs/spec-v0.4
@@ -1 +1 @@
-Subproject commit b462f8452fad8ff254d762cf72283d2e8e00ef27
+Subproject commit f95df21d7e3045a37d2c85e07f90805130fd65be
diff --git a/generator/src/main.rs b/generator/src/main.rs
index 7864aa3..77ee652 100644
--- a/generator/src/main.rs
+++ b/generator/src/main.rs
@@ -347,7 +347,7 @@ fn collect_structs(
         None => match field_names.last() {
             // HACK for an anyOf (string or enum/string)
             Some(&"priority") | Some(&"ticketType") | Some(&"resolution") => TypeInfo {
-                type_declaration: "String".to_string(),
+                type_declaration: "crate::NonEmptyString".to_string(),
                 ..Default::default()
             },
             _ => unimplemented!("expected key 'type' in field '{}'", field_names.join(".")),