Validation Reference

When you submit a BodyLink game, the fail-closed submission gate checks your bundle and — on rejection — names every failing check along with a one-line recommended fix. This page is the reference for those named checks: the code the gate emits, what it means, and the fix.

The report shape is:

{ slug, pass, checks: [ { check, pass, issues: [ { code, message, fix } ] } ] }
        

Run the gate locally to get the same report the developer portal shows:

node scripts/validate-submission.mjs <bundle-dir> --report
        

Each issue belongs to a named check group. The tables below are grouped the same way. Any code not listed falls back to a generic fix ("review the validation message and the Runtime v1 bundle contract, then re-run the validator") — a failing check is never left without a fix.


Manifest & metadata

Checks on bodylink.game.json: the entry shape, the launcher block, and tracking metadata.

Code What it means Recommended fix
bundle.manifest_missing no readable manifest Add a valid bodylink.game.json at the bundle root (valid JSON).
bundle.manifest_invalid manifest does not parse / match schema Fix the bodylink.game.json so it parses and matches the manifest schema.
bundle.manifest_file_missing manifest absent from the exported bundle Include bodylink.game.json in the exported bundle.
bundle.entry_kind entry.kind is not "iframe" Set manifest entry.kind to "iframe" for Runtime v1 bundles.
bundle.entry_missing no entry.html Add manifest entry.html pointing at the bundle HTML entrypoint.
bundle.launcher_missing no launcher block Add a launcher block to the manifest for catalog-ready bundles.
bundle.launcher_field_missing a launcher field is absent Fill the named launcher field (description / color / gridSize / tags / howToPlay).
bundle.launcher_metadata_missing required top-level metadata absent Provide the required manifest metadata (id, name, version, runtimeRange).
bundle.launcher_metadata_invalid version is not valid SemVer Make manifest.version a valid SemVer (e.g. 1.0.0).
bundle.launcher_tracking_focus invalid launcher.trackingFocus Set launcher.trackingFocus to one of: hand, body, none.
bundle.launcher_tracking_preset preset missing when a camera is required Set launcher.trackingPreset to a valid preset when requiresCamera is true.
bundle.launcher_tracking_tier invalid launcher.trackingTier Set launcher.trackingTier to one of: standard, high, custom.
bundle.launcher_tracking_policy_invalid trackingPolicy is not an object Make launcher.trackingPolicy an object when declared.
bundle.launcher_tracking_custom_policy_missing custom tier without a policy Provide an explicit launcher.trackingPolicy for trackingTier: "custom".
bundle.launcher_tracking_policy_profile invalid trackingPolicy.profile Set trackingPolicy.profile to one of: stability, latency, precise, balanced.
bundle.launcher_tracking_pose_model invalid trackingPolicy.poseModel Set trackingPolicy.poseModel to one of: lite, full.
bundle.launcher_tracking_policy_tier raw budgets without custom tier Raw trackingPolicy budgets require launcher.trackingTier: "custom".

Capabilities & SDK compatibility

Checks that your bundle declares the iframe/SDK capabilities and stays within the SDK surface (no host-internal references, all module specifiers resolved).

Code What it means Recommended fix
bundle.capability_missing iframe/SDK capabilities not declared Declare the required capabilities (iframe.bundle.v1, sdk.proxy.v1).
bundle.tracking_invalid manifest tracking block invalid Fix the manifest tracking block so it matches the tracking schema.
bundle.tracking_optional_invalid optional tracking declaration invalid Correct the optional tracking declaration to a valid shape.
bundle.tracking_optional_capability_missing optional feature lacks its capability Add the capability that the declared optional tracking feature requires.
bundle.sdk_facade_missing the SDK facade is missing Keep the SDK facade in the bundle, or externalize the SDK via the lock's external-SDK descriptor.
bundle.sdk_only_forbidden_reference imports a host-internal package Remove the host-internal reference; game bundles may use only the game-kit / iframe-sdk surface.
bundle.sdk_only_unresolved_module_import a bare/unresolved import (unbuilt source) Bundle or remove the unresolved module import; SDK-only bundles must resolve all specifiers.
bundle.externalize_sdk_integrity_required externalizing the SDK without an SRI Provide the SDK SRI integrity before externalizing the SDK.

Catalog assets

Checks on the catalog thumbnail and preview imagery.

Code What it means Recommended fix
bundle.catalog_invalid manifest.catalog is not an object Make manifest.catalog an object when declared.
bundle.catalog_asset_missing thumbnail/preview missing Add the missing catalog asset (thumbnail and preview) as bundle-relative files.
bundle.catalog_asset_metadata image media metadata absent Declare image media metadata (type: image/*) for the catalog asset.

Asset sizes

Code What it means Recommended fix
bundle.asset_too_large a bundle file exceeds the per-file limit Compress or split the file so each bundle file is under the per-file size limit.

Bundle structure & offline safety

Checks that every path is bundle-relative and offline-safe, the iframe session is locked down, and there are no runtime module loads (which opaque-origin iframes cannot satisfy).

Code What it means Recommended fix
bundle.asset_missing a manifest asset path does not resolve Ensure every manifest asset path resolves to an existing bundle file.
bundle.path_empty an empty bundle-relative path Provide a non-empty bundle-relative path.
bundle.path_not_relative an absolute or URL-like path Use a bundle-relative path (no absolute or URL-like paths).
bundle.path_traversal a .. traversal segment Remove .. traversal segments from the path.
bundle.iframe_session invalid iframeSession block Provide a valid manifest.iframeSession block.
bundle.parent_origins allowedParentOrigins not declared Declare iframeSession.allowedParentOrigins explicitly.
bundle.parent_origin_wildcard allowedParentOrigins contains "*" Replace the wildcard parent origin with explicit origins.
bundle.sandbox bad iframeSession.sandbox Set a valid iframeSession.sandbox (allow-scripts only; never allow-same-origin).
bundle.network_not_offline network not disabled Set permissions.network to false for offline Runtime v1 bundles.
bundle.html_external_reference HTML references an external URL Make HTML references bundle-relative; external URLs are not allowed in offline bundles.
bundle.html_reference_missing HTML points at a missing file Point the HTML reference at an existing bundle file.
bundle.opaque_origin_module_script a module <script> entrypoint Drop module <script> entrypoints in allow-scripts-only bundles (opaque-origin modules need CORS).
bundle.opaque_origin_module_script_not_bundle_relative module <script> src not bundle-relative Make the module script src bundle-relative.
bundle.opaque_origin_import_meta import.meta usage Remove import.meta usage; it is unavailable in opaque-origin bundles.
bundle.opaque_origin_dynamic_import dynamic import() at runtime Remove dynamic import(); opaque-origin bundles cannot fetch modules at runtime.
bundle.zip_invalid_path bad zip entry path Fix the zip entry path (bundle-relative, no traversal).
bundle.zip_invalid malformed archive Re-export the bundle zip; the archive is malformed.
bundle.zip_path_traversal traversal in a zip entry Remove traversal segments from zip entry paths.
bundle.zip_unsupported_method unsupported compression method Re-export using a supported zip compression method (store or deflate).
bundle.zip_size_mismatch entry size/hash mismatch Re-export the zip; an entry size/hash does not match the lock.

Offline integrity & lock

Checks on the integrity lock (bodylink.bundle.lock.json) and the index.html entry. These almost always mean "re-export — do not hand-edit the lock."

Code What it means Recommended fix
bundle.index_missing no index.html Include index.html in the bundle.
bundle.lock_missing no lock file Include bodylink.bundle.lock.json in the exported bundle.
bundle.lock_version stale lock version Re-export with the current bundle lock version.
bundle.lock_boundary lock boundary mismatch Re-export; the lock's export boundary does not match the bundle contents.
bundle.lock_file_hash_missing a file hash is missing Re-export; the lock is missing a file hash.
bundle.lock_asset_hash_missing an asset hash is missing Re-export; the lock is missing an asset hash.
bundle.lock_invalid malformed lock Re-export; bodylink.bundle.lock.json is malformed.

Runtime boot

The optional runtime check boots your bundle for real in a headless browser. It is skip-clean (not a failure) when no browser is available locally — but the portal's CI runner always runs it.

Code What it means Recommended fix
runtime.boot the live boot did not reach a healthy state Boot locally (npm run dev:hosted), open the bundle, and resolve the SDK-handshake / tracking-frame / console failures before resubmitting.

Process-level

Aggregate codes emitted when a validation stage fails as a whole.

Code What it means Recommended fix
bundle.validation_failed one or more validation issues Resolve the reported validation issues before exporting.
bundle.sdk_only_validation_failed one or more SDK-only issues Resolve the SDK-only validation issues before exporting.
bundle.zip_validation_failed one or more zip issues Resolve the validation issues before producing the bundle zip.

For the build, validation, and submission workflow these codes fit into, see the Developer Guide.