zaproxy/zaproxy · error · IllegalStateException

The interface error message provider must not be set if usin

Error message

The interface error message provider must not be set if using an interface provider.

What it means

A ScriptsCache Configuration may provide either an interfaceProvider (which supplies the script instance directly) or an interfaceErrorMessageProvider (for default providers) — but build() throws IllegalStateException if both are set, because the error message provider is meaningless when an interface provider is used.

Source

Thrown at zap/src/main/java/org/zaproxy/zap/extension/script/ScriptsCache.java:390

            /**
             * Builds the configuration from the specified data.
             *
             * @return the build configuration.
             * @throws IllegalStateException if the script type or the target interface is not set.
             *     Or, the interface error message provider is set at the same time as the interface
             *     provider. The error message provider is not used when using an interface
             *     provider.
             */
            public final Configuration<T> build() {
                if (scriptType == null || scriptType.isEmpty()) {
                    throw new IllegalStateException("The script type must be set.");
                }
                if (targetInterface == null) {
                    throw new IllegalStateException("The target interface must be set.");
                }

                if (interfaceProvider != null && interfaceErrorMessageProvider != null) {
                    throw new IllegalStateException(
                            "The interface error message provider must not be set if using an interface provider.");
                }

                return new Configuration<>(
                        scriptType,
                        targetInterface,
                        interfaceProvider,
                        interfaceErrorMessageProvider);
            }
        }
    }

    /**
     * An action applied on a script, through the interface.
     *
     * @param <T> the type of the interface.
     */
    public interface ScriptAction<T> {

View on GitHub (pinned to 9d1970a436)

Solutions

  1. Remove the setInterfaceErrorMessageProvider call when using an interfaceProvider
  2. Keep interfaceErrorMessageProvider only for configurations using the default script-loading path
  3. Split into two separate Configurations if both behaviors are needed

Example fix

// before
Configuration<MyApi> cfg = new Configuration<MyApi>()
    .setScriptType("my-type")
    .setTargetInterface(MyApi.class)
    .setInterfaceProvider(s -> myImpl)
    .setInterfaceErrorMessageProvider(s -> "err")
    .build();
// after
Configuration<MyApi> cfg = new Configuration<MyApi>()
    .setScriptType("my-type")
    .setTargetInterface(MyApi.class)
    .setInterfaceProvider(s -> myImpl)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (interfaceProvider != null && interfaceErrorMessageProvider != null) throw new IllegalStateException("choose one provider style");

Try / catch

try { cfg = builder.build(); } catch (IllegalStateException e) { log.error("Conflicting providers: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling both .setInterfaceProvider(...) and .setInterfaceErrorMessageProvider(...) on the same Configuration builder before .build().

Common situations: Add-on code copied from two different examples that each set one of the options; incremental refactoring that added an interface provider but left the old error-message provider in place.

Related errors


AI-assisted analysis of zaproxy/zaproxy@9d1970a436 (2026-09-05). Data as JSON: /api/errors/ea0341a9e0e1df39. Report an issue: GitHub.