github/copilot-sdk · error · IllegalArgumentException

options must not be null

Error message

options must not be null

What it means

CopilotSession.setModel(SetModelOptions) validates its argument before issuing the RPC and throws IllegalArgumentException('options must not be null') when called with null. The SDK requires an options object even if only changing the model, so callers must construct SetModelOptions.

Solutions

  1. Pass a constructed SetModelOptions instance with at least a model value set.
  2. Return early when no model option is configured instead of calling setModel with null.
  3. Add a caller-side null check before invoking setModel.

Example fix

// before
session.setModel(config.getModelOptions()); // null when unset
// after
var options = config.getModelOptions();
if (options != null) {
    session.setModel(options);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (options == null) {
    return; // nothing to set
}

Type guard

boolean hasOptions(com.github.copilot.rpc.SetModelOptions o) { return o != null; }

Try / catch

try {
    session.setModel(options);
} catch (IllegalArgumentException e) {
    LOG.warning("setModel rejected: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling session.setModel(null) after the session is confirmed non-terminated (CopilotSession.java:2237). Note ensureNotTerminated() runs first, so a terminated session throws IllegalStateException instead.

Common situations: A caller builds options conditionally (e.g. only when a model preference exists) and passes the null result straight to setModel; typical in config-driven code where the model setting is absent.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/27537d801c6b9745. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/CopilotSession.java:2237

     * session.setModel(new SetModelOptions().setModel("auto").setAutoTier(AutoTier.INTELLIGENCE)).get();
     * session.setModel(new SetModelOptions().setModel("auto").setResetAutoTier(true)).get();
     * }</pre>
     *
     * @param options
     *            the switch settings; the model ID is required
     * @return a future that completes when the model switch is acknowledged
     * @throws IllegalArgumentException
     *             if {@code options} is {@code null}, if it carries no model ID, or
     *             if it requests both an explicit Auto tier and a return to
     *             provider-default Auto routing
     * @throws IllegalStateException
     *             if this session has been terminated
     * @since 1.6.0
     */
    public CompletableFuture<Void> setModel(com.github.copilot.rpc.SetModelOptions options) {
        ensureNotTerminated();
        if (options == null) {
            throw new IllegalArgumentException("options must not be null");
        }
        if (options.getModel() == null) {
            throw new IllegalArgumentException("options must specify a model");
        }
        if (options.getAutoTier() != null && options.isResetAutoTier()) {
            throw new IllegalArgumentException(
                    "setModel cannot combine an explicit autoTier with resetAutoTier; choose one");
        }
        var generatedReasoningSummary = options.getReasoningSummary() == null
                ? null
                : com.github.copilot.generated.rpc.ReasoningSummary.fromValue(options.getReasoningSummary());
        var params = new SessionModelSwitchToParams(sessionId, options.getModel(),
                toGeneratedAutoTier(options.getAutoTier()), options.getReasoningEffort(), generatedReasoningSummary,
                null, toGeneratedCapabilities(options.getModelCapabilities()), null, null, null, null, null, null, null,
                null, null);
        if (!options.isResetAutoTier()) {
            return getRpc().model.switchTo(params).thenApply(r -> null);
        }

View on GitHub (pinned to cd8cf15dc3)