Tencent/VasSonic · error · IllegalStateException

SonicEngine::createInstance() needs to be called before…

Error message

SonicEngine::createInstance() needs to be called before SonicEngine::getInstance()

What it means

SonicEngine is the central singleton of the Sonic SDK and must be initialized with createInstance(new SonicRuntime..., SonicConfig) before use. getInstance() throws this IllegalStateException when the engine was never created, preventing use of an uninitialized engine.

Solutions

  1. Call SonicEngine.createInstance(new SonicRuntimeImpl(application), sonicConfig) once in Application.onCreate before any Sonic API use
  2. Use SonicEngine.isInstanceCreated() to gate call sites or lazily create the engine before use
  3. Ensure all processes that use Sonic perform their own createInstance
  4. In tests, add a setup step that calls createInstance with a mock SonicRuntime

Example fix

// before
String sid = SonicEngine.getInstance().makeSessionId(url); // throws
// after
@Override public void onCreate() {
  SonicEngine.createInstance(new SonicRuntimeImpl(this), new SonicConfig.Builder().build());
}
String sid = SonicEngine.getInstance().makeSessionId(url);
Defensive patterns

Strategy: validation

Validate before calling

if (!SonicEngine.isInstanceCreated()) {
  SonicEngine.createInstance(new SonicRuntimeImpl(app), new SonicConfig.Builder().build());
}

Type guard

// Java: central accessor
static synchronized SonicEngine engine(Application app) {
  if (!SonicEngine.isInstanceCreated())
    SonicEngine.createInstance(new SonicRuntimeImpl(app), new SonicConfig.Builder().build());
  return SonicEngine.getInstance();
}

Try / catch

try {
  SonicEngine.getInstance().makeSessionId(url);
} catch (IllegalStateException e) {
  SonicEngine.createInstance(runtime, config); // recover then retry once
}

Prevention

When it happens

Trigger: Calling SonicEngine.getInstance() (directly or indirectly, e.g. via makeSessionId) before SonicEngine.createInstance(runtime, config) has completed.

Common situations: Skipping SDK init in Application.onCreate; calling Sonic APIs from another thread/process before init; unit tests that exercise Sonic APIs without a runtime; initializing Sonic in an Activity that isn't the entry point.

Related errors


AI-assisted analysis of Tencent/VasSonic@59936beff6 (2026-09-08). Data as JSON: /api/errors/79d85d9bbc584959. Report an issue: GitHub.

Appendix: source

Thrown at sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicEngine.java:77

    private final ConcurrentHashMap<String, SonicSession> runningSessionHashMap = new ConcurrentHashMap<String, SonicSession>(5);


    private SonicEngine(SonicRuntime runtime, SonicConfig config) {
        this.runtime = runtime;
        this.config = config;
    }

    /**
     * Returns a SonicEngine instance
     * <p>
     * Make sure {@link #createInstance(SonicRuntime, SonicConfig)} has been called.
     *
     * @return SonicEngine instance
     * @throws IllegalStateException if {@link #createInstance(SonicRuntime, SonicConfig)} hasn't been called
     */
    public static synchronized SonicEngine getInstance() {
        if (null == sInstance) {
            throw new IllegalStateException("SonicEngine::createInstance() needs to be called before SonicEngine::getInstance()");
        }
        return sInstance;
    }

    /**
     * Check if {@link #getInstance()} is ready or not.
     * <p><b>Note: {@link #createInstance(SonicRuntime, SonicConfig)} must be called if {@code false} is returned.</b></p>
     * @return
     *      Return <code>true</code> if {@link #sInstance} is not null, <code>false</code> otherwise
     */
    public static synchronized boolean isGetInstanceAllowed() {
        return null != sInstance;
    }

    /**
     * Create SonicEngine instance. Meanwhile it will initialize engine and SonicRuntime.
     * @param runtime SonicRuntime
     * @param config SonicConfig

View on GitHub (pinned to 59936beff6)