Skip to content

createViewModelInstance(.viewModelDefault) returns invalid instance without throwing when no view model is linked to artboard #441

@cerupcat

Description

@cerupcat

Summary

File.createViewModelInstance(.viewModelDefault(from: .artboardDefault(artboard))) skips all validation for the .viewModelDefault case and always returns a ViewModelInstance — even when no view model is linked to the artboard. The returned instance is invalid, but no Swift error is thrown. When this instance is subsequently bound via stateMachine.bindViewModelInstance(instance) (e.g. via Rive(dataBind: .instance(instance))), it produces continuous C++ errors:

Could not find a View Model linked to Artboard <ArtboardName>.
ERROR : State machine 0x1 not found for binding view model.
ERROR : State machine 0x1 not found for advance.

This affects any animation-only .riv file (no data binding configured) that is loaded via the async runtime.

Steps to Reproduce

  1. Have a .riv file whose artboard has a state machine but no linked view model (pure animation, no data binding).
  2. In the async runtime, call:
    let instance = try await file.createViewModelInstance(
        .viewModelDefault(from: .artboardDefault(artboard))
    )
  3. Pass instance to Rive(dataBind: .instance(instance)).
  4. Observe "Could not find a View Model linked to Artboard ..." warning and continuous "State machine 0x1 not found for advance" errors.

Expected Behavior

createViewModelInstance(.viewModelDefault) should throw FileError.invalidViewModel (or similar) when no view model is linked to the artboard, consistent with how .name(_, from: .name(_)) validates its inputs. Callers can then handle the error gracefully.

Alternatively, Rive(dataBind: .auto) — which uses try? — should be a safe fallback, but it is not: since createViewModelInstance never throws for .viewModelDefault, try? still returns a non-nil (invalid) instance and binds it, producing the same errors.

Actual Behavior

.viewModelDefault hits case .viewModelDefault: break — intentional skip of validation — and creates a ViewModelInstance backed by a C++ object that will fail silently when bound. No Swift error surfaces.

Suggested Fix

Add validation for the .viewModelDefault case: check whether the artboard has any linked view model before creating the instance, and throw if none is found. This would make the behavior consistent with other ViewModelInstanceSource cases and allow Rive(dataBind: .auto) to work correctly as a safe fallback.

Workaround

Call file.getViewModelNames() before createViewModelInstance and skip instance creation (use dataBind: .none) when the list is empty.

Environment

  • rive-ios version: 6.19+
  • Platform: iOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions