xpipe-io/xpipe · error · IllegalStateException
Local shell not initialized yet
Error message
Local shell not initialized yet
What it means
LocalShell.getShell() returns the cached, lazily-initialized local shell connection. If LocalShell.init() has not yet run (static field local == null), there is no shell to hand out and an IllegalStateException is thrown. This is an initialization-order guard, not a shell failure.
Source
Thrown at app/src/main/java/io/xpipe/app/process/LocalShell.java:122
localPowershell = ProcModuleProvider.get()
.createLocalProcessControl(false)
.subShell(ShellDialects.POWERSHELL)
.start();
localPowershell.getShellDialect().getDumbMode().throwIfUnsupported();
} catch (Exception ex) {
localPowershell = null;
ErrorEventFactory.fromThrowable(ex)
.description("Failed to start local powershell process")
.handle();
}
return Optional.ofNullable(localPowershell);
}
@SneakyThrows
public static ShellControl getShell() {
if (local == null) {
throw new IllegalStateException("Local shell not initialized yet");
}
return local.start();
}
public static ShellDialect getDialect() {
return ProcModuleProvider.get().getEffectiveLocalDialect();
}
}
View on GitHub (pinned to d85ca821ba)
Solutions
- Ensure LocalShell.init() runs before any code that resolves local-machine stores
- In tests, call the init/test hook to bootstrap a local shell in setup
- Check startup logs for an earlier exception that prevented shell initialization
Example fix
// before var shell = LocalShell.getShell(); // after LocalShell.init(); // in setup/bootstrap, before first use var shell = LocalShell.getShell();
Defensive patterns
Strategy: try-catch
Type guard
boolean localShellReady() { try { var f = LocalShell.class.getDeclaredField("local"); f.setAccessible(true); return f.get(null) != null; } catch (Exception e) { return false; } } Try / catch
try { var shell = LocalShell.getShell(); ... } catch (IllegalStateException e) { if (e.getMessage().equals("Local shell not initialized yet")) { LocalShell.init(); shell = LocalShell.getShell(); } else throw e; } Prevention
- Initialize LocalShell in app bootstrap before any store access
- In tests, bootstrap the shell in @SetUp
- Don't swallow exceptions during shell init
When it happens
Trigger: Any code path calling LocalShell.getShell() before LocalShell.init() completed, or after initialization failed silently leaving local null.
Common situations: Calling store/query APIs very early during app startup before the local shell bootstrap; unit tests instantiating classes that depend on LocalShell without initializing it; initialization failure swallowed earlier in startup.
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 xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/0010f2ec473e8cd9.
Report an issue: GitHub.