diff --git a/CHANGES b/CHANGES
index b5bafb878..e2d788177 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,7 @@ Emulation fixes:
 Other fixes:
  - Switch: Fix threading-related crash on second launch
  - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421)
+ - Core: Fix crashes if core directories aren't set
 Misc:
  - Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424)
 
diff --git a/src/core/core.c b/src/core/core.c
index 343e11ce8..8609b8efd 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -157,10 +157,16 @@ bool mCorePreloadFile(struct mCore* core, const char* path) {
 }
 
 bool mCoreAutoloadSave(struct mCore* core) {
+	if (!core->dirs.save) {
+		return false;
+	}
 	return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.save, ".sav", O_CREAT | O_RDWR));
 }
 
 bool mCoreAutoloadPatch(struct mCore* core) {
+	if (!core->dirs.patch) {
+		return false;
+	}
 	return core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ups", O_RDONLY)) ||
 	       core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ips", O_RDONLY)) ||
 	       core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".bps", O_RDONLY));
@@ -217,6 +223,9 @@ bool mCoreLoadState(struct mCore* core, int slot, int flags) {
 }
 
 struct VFile* mCoreGetState(struct mCore* core, int slot, bool write) {
+	if (!core->dirs.state) {
+		return NULL;
+	}
 	char name[PATH_MAX];
 	snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot);
 	return core->dirs.state->openFile(core->dirs.state, name, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY);