perwendel/spark · error · IllegalStateException

This must be done after route mapping has begun

Error message

This must be done after route mapping has begun

What it means

Service.port() returns the port the embedded Spark server is actually listening on. That value only exists once route mapping has begun and the server configuration has been initialized; before that the port field is meaningless. Spark therefore throws IllegalStateException if port() is called too early, as documented by its @throws clause.

Solutions

  1. Move the port() call after route mapping has begun (after at least one get/post/put/etc. or staticFiles call), ideally after init() and awaitInitialization().
  2. If you need the port before mapping, set it explicitly with port(4567) and use your own constant instead of reading it back.
  3. Use awaitInitialization() first, then call port() to ensure the server is fully started.

Example fix

// before
Spark.get("/hello", (req, res) -> "hi");
int p = Spark.port(); // may throw if called before mapping
// after
Spark.get("/hello", (req, res) -> "hi");
Spark.awaitInitialization();
int p = Spark.port(); // safe
Defensive patterns

Strategy: try-catch

Validate before calling

if (sparkService != null && isRouteMappingStarted()) {
    int p = sparkService.port();
}

Type guard

boolean portReadable(spark.Service s) { return s != null && isRouteMappingStarted(); } // no public initialized check; track mapping start yourself

Try / catch

try {
    int p = Spark.port();
} catch (IllegalStateException e) {
    // called before route mapping; use configured default instead
    int p = DEFAULT_PORT;
}

Prevention

When it happens

Trigger: Calling port() on the Service instance (or the static Spark.port()) before any route mapping call (get/post/staticFiles etc.) has triggered initialization — e.g. calling it immediately at the top of main() before mapping routes.

Common situations: Logging 'running on port X' before routes are mapped; reading the port in a constructor or static initializer; frameworks/integration code that query the port at startup before defining routes.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of perwendel/spark@1973e402f5 (2026-09-10). Data as JSON: /api/errors/afe175eba82c3311. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/spark/Service.java:185

    public synchronized Service port(int port) {
        if (initialized) {
            throwBeforeRouteMappingException();
        }
        this.port = port;
        return this;
    }

    /**
     * Retrieves the port that Spark is listening on.
     *
     * @return The port Spark server is listening on.
     * @throws IllegalStateException when the server is not started
     */
    public synchronized int port() {
        if (initialized) {
            return port;
        } else {
            throw new IllegalStateException("This must be done after route mapping has begun");
        }
    }

    /**
     * Set the connection to be secure, using the specified keystore and
     * truststore. This has to be called before any route mapping is done. You
     * have to supply a keystore file, truststore file is optional (keystore
     * will be reused). By default, client certificates are not checked.
     * This method is only relevant when using embedded Jetty servers. It should
     * not be used if you are using Servlets, where you will need to secure the
     * connection in the servlet container
     *
     * @param keystoreFile       The keystore file location as string
     * @param keystorePassword   the password for the keystore
     * @param truststoreFile     the truststore file location as string, leave null to reuse
     *                           keystore
     * @param truststorePassword the trust store password
     * @return the object with connection set to be secure

View on GitHub (pinned to 1973e402f5)