library(croissant)4 Validation
validate_croissant(x) checks Croissant metadata and returns every problem found as one CroissantIssues object. x is a Croissant object, or a path, URL, or JSON string, which is read first. The checks follow those of mlcroissant 1.1.1.
4.1 Issues
Each issue has a severity. An error makes the metadata invalid. A warning names an absent recommended property, or a construct that is read in a way the author may not intend.
The following object has five errors: a file without encodingFormat and without a checksum, a source that names a file that does not exist, and a field without a source or data type.
x <- Croissant(
name = "flawed",
distribution = list(FileObject(id = "data.csv", content_url = "data.csv")),
record_set = list(
RecordSet(
id = "rs",
field = list(
Field(
id = "rs/a",
data_type = "sc:Integer",
source = Source(file_object = "missing.csv", extract = Extract(column = "a"))
),
Field(id = "rs/b")
)
)
)
)
issues <- validate_croissant(x)
issues<CroissantIssues>
5 errors, 4 warnings
Errors
- [data.csv] The FileObject has no encodingFormat, which is mandatory.
- [data.csv] The FileObject has neither md5 nor sha256. Add the sha256 checksum of the file at contentUrl.
- [rs/a] The source names "missing.csv", but no node has that @id. Name the @id of a FileObject, FileSet, RecordSet, or Field of this dataset.
- [rs/b] The field defines neither source nor value. Add a source that names the file or field its values come from, or a constant value.
- [rs/b] The field has no dataType, and its source is not a field to take one from. Add a dataType, such as sc:Text or sc:Integer.
Warnings
- [Croissant(flawed)] The recommended property citeAs is absent.
- [Croissant(flawed)] The recommended property datePublished is absent.
- [Croissant(flawed)] The recommended property license is absent.
- [Croissant(flawed)] The recommended property version is absent.
print() shows the counts, then the errors, then the warnings. Each line starts with the node: its @id, or its class and name when it has no @id.
is_valid() returns TRUE when the object holds no error. Warnings do not affect it.
is_valid(issues)[1] FALSE
issues@issues is a data.frame with one row per issue and the character columns severity ("error" or "warning"), check, node, and message. Identical issues appear once.
issues@issues[, c("severity", "check", "node")] severity check node
1 warning recommended_property Croissant(flawed)
2 warning recommended_property Croissant(flawed)
3 warning recommended_property Croissant(flawed)
4 warning recommended_property Croissant(flawed)
5 error missing_property data.csv
6 error missing_checksum data.csv
7 error unresolved_reference rs/a
8 error missing_source rs/b
9 error missing_data_type rs/b
When x is a document rather than an object, validate_croissant() also reports the problems that read_croissant() raises as an error, such as a value of the wrong JSON type, together with the structural issues. A version error is reported with check version, and any other input error, such as invalid JSON or a missing file, with check input.
doc <- sub('"name": "flawed"', '"name": 42', write_croissant(x))
validate_croissant(doc)<CroissantIssues>
6 errors, 4 warnings
Errors
- [Croissant] Property name must be text. Received: 42
- [data.csv] The FileObject has no encodingFormat, which is mandatory.
- [data.csv] The FileObject has neither md5 nor sha256. Add the sha256 checksum of the file at contentUrl.
- [rs/a] The source names "missing.csv", but no node has that @id. Name the @id of a FileObject, FileSet, RecordSet, or Field of this dataset.
- [rs/b] The field defines neither source nor value. Add a source that names the file or field its values come from, or a constant value.
- [rs/b] The field has no dataType, and its source is not a field to take one from. Add a dataType, such as sc:Text or sc:Integer.
Warnings
- [Croissant] The recommended property citeAs is absent.
- [Croissant] The recommended property datePublished is absent.
- [Croissant] The recommended property license is absent.
- [Croissant] The recommended property version is absent.
4.2 Checks
4.2.1 Errors
| Check | Condition |
|---|---|
type |
A value has the wrong JSON type for its property, or a node is not a JSON object |
node_type |
A node’s @type does not include its class’s type (sc:Dataset, cr:FileObject, cr:FileSet, cr:RecordSet, cr:Field) |
duplicate_property |
Two keys of one node canonicalize to the same property |
missing_property |
A FileObject has no encodingFormat, or no contentUrl when it is not contained in another file; a FileSet has no encodingFormat or includes |
missing_checksum |
A FileObject that is not contained in another file has neither md5 nor sha256, in a dataset without isLiveDataset: true |
invalid_id |
An @id contains whitespace |
duplicate_id |
Two nodes share an @id |
unresolved_reference |
A containedIn, source, or references names an @id that no node has |
source_target |
A source names none, or more than one, of fileObject, fileSet, and field |
missing_source |
A field without subfields, in a record set without inline data, has neither source nor value; or a field has both |
missing_data_type |
A field without subfields has no dataType and its source is not a field; or a field with a constant value has no dataType |
undeclared_join |
The fields of a record set read from two sources and no field joins them with references |
inline_data |
Inline data is an empty array, holds a record that is not an object, or holds a record whose keys are not exactly the field @ids |
array_shape |
arrayShape is given without isArray: true, or has dimensions that are not integers |
transform |
A transform defines no transformation, or more than one of format, jsonPath, regex, replace, and separator |
version |
The document conforms to a Croissant version other than 1.0 or 1.1 |
input |
The input cannot be read, for example invalid JSON or a missing file |
4.2.2 Warnings
| Check | Condition |
|---|---|
recommended_property |
The dataset has no citeAs, datePublished, license, or version |
missing_property |
The document has no conformsTo, and is read as Croissant 1.0 |
missing_id |
A node has no @id, so no other node can reference it |
unresolved_key |
A record set key names no field, by @id, by @id relative to the record set, or by name |
undefined_term |
A Croissant term is used as a key without a definition in the @context |
4.2.3 Differences from mlcroissant
mlcroissant assigns a blank-node @id to a node without one and checks neither record set keys nor JSONPath syntax. croissant reports a missing @id and an unresolved key as warnings and does not parse JSONPath expressions during validation. read_record_set() raises an error of class croissant_jsonpath_error for a JSONPath that it does not evaluate; see Reading records.
The package test suite compares validate_croissant() with mlcroissant 1.1.1 on the 46 example documents and 15 invalid test documents of the MLCommons repository. On the examples, both report no error and the same absent recommended properties. On the invalid documents, the errors reported correspond one to one, with two exceptions that mlcroissant reports and croissant does not: two errors that follow from a whitespace @id, and a second message for one unresolved source.
4.3 A complete record
The metadata below sets every recommended property, the checksum, and the encoding format, and validates without issue.
dir <- tempfile()
dir.create(dir)
writeLines(c("a", "1", "2"), file.path(dir, "data.csv"))
fixed <- Croissant(
name = "fixed",
license = "CC0-1.0",
cite_as = "Fixed data (2026).",
date_published = "2026-10-27",
dataset_version = "1.0.0",
distribution = list(
FileObject(
id = "data.csv",
content_url = "data.csv",
encoding_format = "text/csv",
md5 = unname(tools::md5sum(file.path(dir, "data.csv")))
)
),
record_set = list(
RecordSet(
id = "rs",
field = list(
Field(
id = "rs/a",
data_type = "sc:Integer",
source = Source(file_object = "data.csv", extract = Extract(column = "a"))
)
)
)
)
)
validate_croissant(fixed)<CroissantIssues>
0 errors, 0 warnings