Export report and exit codes
The command line exporter tells a complete export from a partial one by its exit code and, on request, by a JSON report. Without the new options the output (IFC, JSON, standard error text) and the exit code of a complete export are unchanged.
Options
| Option | Effect |
|---|---|
--report <report.json> |
Write the JSON report of the run to this path. Written on success and on failure. |
--allow-partial |
Export what was read when a reader limit cut a stream. The exit code is then 0 and the report says "status": "partial". Cannot be combined with --strict. |
--strict |
Fail with exit code 6 instead of 0 when the read is partial even without hitting a limit (a member failed to decode, was rebuilt by structural recovery, or decoded without a matching checksum, or the element table decoded no row). Nothing is exported; the report lists the streams and the reason. Cannot be combined with --allow-partial. |
--raise-limits |
Raise the limits listed below for a very large model. |
Exit codes
| Code | Name | Meaning |
|---|---|---|
| 0 | success | The export was written. With --allow-partial or, without --strict, after members of a stream failed to decode or were recovered, the report can still say "status": "partial": read it when you need to know, or pass --strict to make partial reads fail. |
| 1 | usage | The command line is wrong (unchanged from earlier versions). |
| 2 | input error | The input cannot be read: the file does not exist or cannot be opened, is empty, is not a compound file, or is cut or damaged so that a stream ends before its declared length. One line on standard error, no stack trace, nothing exported. |
| 3 | limit exceeded | A stream exceeded a limit of the reader and the read was cut. Nothing is exported unless --allow-partial is given. A stream longer than the platform allows in one array cannot be read at all: that case exits with 3 even with --allow-partial. |
| 4 | decode error | The compound file is readable but a decoder failed on its content (damaged or unsupported data). One line on standard error; the report holds the exception with its stack trace. |
| 5 | refused | downgrade --check refused the request (for example a source newer than release 2026, a profile not older than the source, a saving release that does not match the class table, or an ambiguous class name). One line on standard error. |
| 6 | partial read | --strict was given and the read finished partial without exceeding a limit (members of a stream failed to decode, were rebuilt by structural recovery, or decoded without a matching checksum, or the element table decoded no row). One line on standard error naming the streams and the reason, nothing exported; the report holds the stream counts and issues[]. |
A crash that is none of these (a defect in the exporter after the read) still ends the process with the runtime's unhandled exception code.
Limits of the reader
These are the limits the reader has. A stream that reaches one is cut, listed under limits.hit and counted as partial.
| Code | Default | Raised by --raise-limits |
What is cut |
|---|---|---|---|
elem-table-recovery-bytes |
268435456 (256 MiB) | the platform array length | The output of the recovery of a damaged Global/ElemTable. The table keeps what the ordinary decoders produced. |
elem-table-recovery-iterations |
4096 | unbounded (each iteration moves forward in the stream) | The number of relocks the recovery of a damaged Global/ElemTable makes. |
array-length |
the platform array length | cannot be raised | A stream of the compound file longer than one array. Exit code 3 whatever the options. |
Report format
The report is one JSON object, UTF-8, property names in camelCase. schema names the format version: rvtio-report/1. New properties can be added within a version; a property is never removed or changed in meaning.
{
"schema": "rvtio-report/1",
"status": "complete",
"exitCode": 0,
"input": { "file": "project.rvt", "bytes": 9293824 },
"limits": { "raised": false, "partialAllowed": false, "strict": false, "hit": [] },
"streams": [
{ "name": "Partitions/0", "rawBytes": 8187086, "members": 695, "decoded": 695,
"failed": 0, "recovered": 0, "unverified": 0, "decodedFraction": 1 }
],
"elements": { "inTable": 8135, "decoded": 8135, "decodedFraction": 1, "undecoded": [] },
"issues": [],
"export": {
"format": "ifc", "considered": 59149, "exported": 28, "skipped": 59121, "exportedFraction": 0.000473,
"skippedByClass": [
{ "class": "OST_Sheets", "reason": "record-outside-exact-element-table", "count": 17580, "examples": [173028, 173029] }
]
}
}
| Property | Meaning |
|---|---|
status |
complete: no limit cut a stream and every member of every stream decoded and verified. partial: a limit cut a stream, a member did not decode, a member decoded without its checksum matching, a member was rebuilt by structural recovery, or the element table decoded no row. failed: the file could not be read at all (exit codes 2 and 4, and 3 for a stream over the platform array length). A read cut by a limit that is not accepted (exit code 3) or a partial read refused by --strict (exit code 6) is partial and has no export property, because nothing was exported. |
exitCode |
The exit code of the process. |
input.file, input.bytes |
File name (no directory) and size of the input. |
error |
Only when status is failed: kind (cannot-open, empty-file, not-a-compound-file, truncated-or-damaged, limit-exceeded, decode-failure), message, and for decode-failure the detail with the stack trace. |
limits.raised, limits.partialAllowed, limits.strict |
Whether --raise-limits, --allow-partial and --strict were given. |
limits.hit[] |
Every stream cut by a limit: stream, limit (code from the table above), value (the limit in force), raisable, detail. |
streams[] |
The partition, Global, Formats and element table streams. members are the gzip members the stream is cut into; decoded produced output; failed produced none and their data is missing (a stream that holds bytes but not one gzip member is one failed member); recovered were rescued by a structural relock; unverified were kept although their checksum did not match or was never checked, which includes every rescued member. decodedFraction is decoded / members. |
elements.inTable, elements.decoded |
Rows of the element table, and those with a parsed record. decodedFraction is their quotient (1 for an empty table). |
issues[] |
Findings that make a read partial, as stream, code, detail: failed-members (one or more gzip members of the stream produced no output), recovered-members (one or more members were rebuilt by structural recovery), unverified-members (one or more members decoded without a matching checksum), and no-rows (Global/ElemTable decoded no row; a project always has elements, so the table did not decode). |
elements.undecoded[] |
Rows of the element table without a parsed record, as class, reason, count, examples. The class of an element that never decoded is unknown. |
export.format |
ifc, json (the compact export) or json-full. |
export.considered, exported, skipped |
Parsed elements the export looked at, wrote, and left out, counted as the exporter counts them (exported counts elements, not product entities: for example, a roof element that writes two product entities, an IfcRoof and an IfcSlab with the same tag, counts once in exported, so the exported total can be below the number of product entities). exportedFraction is exported / considered. |
export.skippedByClass[] |
Every skipped element class with its reason, count and up to five element ids (examples), largest first. The counts add up to export.skipped. |
A complete input also has skipped elements: the exporters leave out element types, annotations, records that only live inside other records and similar. exportedFraction is therefore not a measure of lost data; status, streams and elements are. The reasons below name the rule that left the element out.
Reasons of an IFC export
terrain-or-group-topography, block-only-record, group-template, record-outside-exact-element-table, owned-by-family-nonspatial, rebar-product-not-written, only-unfilled-faces, type-element, non-physical-category, no-project-phase-reference, level-is-not-a-project-level, wall-not-visible, curtain-panel-wall, curtain-child-without-bounds, opening-of-hidden-wall, no-ifc-class-for-category, opening-of-wall-without-body-openings, stacked-wall-container, no-geometry-or-location, hosted-element-without-host, no-geometry-or-bounds, phantom-storey-wall, unplaced-owner-proxy, open-surface-hosted-cutter-proxy, geometryless-product, export-to-ifc-flag-no, reveal-sweep, product-without-body, wall-without-solid, product-without-bounds, invalid-bounds, bounds-under-one-centimetre, container-without-written-parts, non-primary-design-option, outside-export-phase.
A level, a room and the topography that is written as the site are listed as skipped although the IFC holds a storey, a space or the site for them: the list counts product entities of elements, and these are written as the spatial structure.
Reasons of a JSON export
The compact export writes the rows of the element table: block-only-record and record-outside-exact-element-table are the two reasons an element is left out. The full dump (--json-full) writes every parsed element.
Scripting
rvtio project.rvt project.ifc --strict --report project.report.json
case $? in
0) ;; # complete read and export written
2) echo "the file is cut or damaged" ;;
3) echo "limit exceeded: retry with --raise-limits" ;;
4) echo "the content could not be decoded" ;;
6) echo "the read was partial: see streams and issues in project.report.json" ;;
esac