# How to Troubleshoot Common GeoLibre Issues: Layer Loading, Project Saving, and Plugin Activation

> Troubleshoot common GeoLibre issues like layer loading, project saving, and plugin activation. Learn quick fixes for stale cache, sync failures, and plugin states.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: how-to-guide
- Published: 2026-08-03

---

**Most GeoLibre problems stem from stale browser cache, store-layer synchronization failures, or incorrect plugin state—fixable with a hard refresh, store inspection, or verifying desktop build requirements.**

GeoLibre is a store-driven GIS application built on **Zustand** in `@geolibre/core`, where layers, map view, styles, and plugin state converge. When layers fail to load, projects refuse to save, or plugins appear inactive, tracing the issue through the source code reveals three primary failure surfaces: caching, synchronization, and activation flow.

## Stale Browser Cache: The First Suspect

Because **GeoLibre Web** is a single-page application, it aggressively caches HTML and JavaScript assets. An outdated bundle causes unresponsive UI controls, prevents new plugins from loading, or displays stale layer data.

According to the [troubleshooting guide](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/troubleshooting.md), always rule out caching first:

- **Hard refresh:** Ctrl + Shift + R (Windows/Linux) or Cmd + Shift + R (macOS)
- **Private/incognito window:** Opens the app with no cached assets

Force a programmatic hard reload in debug scripts:

```javascript
// Reload the page bypassing the HTTP cache
window.location.reload(true);

```

## Layer Loading Failures: Store-MapLibre Synchronization

Layers are added through the store via `addGeoJsonLayer`, `addVectorLayer`, and other methods, then reconciled with MapLibre by `MapController.syncLayers` in `@geolibre/map`.

### How Layer Sync Works

In [`packages/map/src/MapController.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/map/src/MapController.ts), the `syncLayers` method reads the layer slice from the store and creates or updates MapLibre sources and layers. It handles refresh intervals for live data sources and error reporting to the UI.

When a layer's **source URL is incorrect**, the fetch fails and an error icon appears in the Layers panel. Refreshable layers (WFS, GeoJSON URLs) store a **connection** record in the project file, so failed refreshes display next to the layer entry. See the [layers documentation](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/layers.md) for refresh UI details.

### Debugging Layer State

Inspect the store directly in the browser console:

```javascript
// Inspect all layers
console.log(window.__GEOLIBRE_STORE__.getState().layers);

```

Missing entries indicate the add-layer UI step failed before reaching the store.

### Manually Refresh a Live Layer

After fixing a URL, programmatically reload:

```javascript
import { reloadLayer } from '@geolibre/core';
const layerId = 'my-wfs-layer';
reloadLayer(layerId);

```

Or use the UI: select the layer in the Layers panel, open its refresh configuration, and press **Refresh now**. Error messages appear inline next to the layer entry.

## Project Saving Issues: Desktop vs. Web Builds

**Project saving requires the desktop build.** The browser version lacks native filesystem dialogs and falls back to a download dialog instead. Autosave writes snapshots to **IndexedDB** every few seconds.

### Save Workflow Architecture

The core serialization logic lives in [`packages/core/src/project.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/project.ts):

- **`projectFromStore`** — Converts the in-memory store to a [`.geolibre.json`](https://github.com/opengeos/GeoLibre/blob/main/.geolibre.json) file
- **`parseProject`** — Rehydrates a project file back into store state

These functions power both the desktop "Save" command and the autosave snapshot builder.

### Troubleshooting Save Failures

| Symptom | Cause | Solution |
|---------|-------|----------|
| "Save" button disabled or greyed out | Running web build | Launch the **Tauri desktop app** |
| Error on save | Project path not writable | Verify [`.geolibre.json`](https://github.com/opengeos/GeoLibre/blob/main/.geolibre.json) path permissions |
| Unexpected data loss | Tab closed without saving | Restore from **IndexedDB autosave** prompt on next launch |

When a browser tab closes unexpectedly, GeoLibre displays a *Recover unsaved work?* prompt if a newer IndexedDB snapshot exists. Accept to restore the last autosaved state.

Reference the [projects documentation](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/projects.md) for detailed save workflow and autosave limits.

## Plugin Activation Problems

Plugins are registered in `packages/plugins` and activated via the Plugins menu. After activation, a checkmark appears next to the plugin entry, and any map controls render in the map corner.

### Plugin Architecture

Key files in the activation flow:

- **[`packages/plugins/src/index.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/index.ts)** — Registers built-in plugins and loads external zip-based plugins
- **[`apps/geolibre-desktop/src/hooks/usePlugins.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/hooks/usePlugins.ts)** — Manages plugin lifecycle and activation state

The store's `plugins` slice tracks each plugin's ID with an `active: true|false` flag that the UI reads.

### Debugging Plugin Activation

If activation appears to do nothing:

1. **Rule out stale cache** — Hard refresh or incognito window
2. **Check Network tab** — Confirm the plugin's JS bundle loads without 404/500 errors
3. **Verify store state**:

```javascript
// Inspect plugin activation status
console.log(window.__GEOLIBRE_STORE__.getState().plugins);

```

Missing entries or `active: false` indicate the activation UI step failed.

Activate programmatically from the console:

```javascript
import { togglePlugin } from '@geolibre/core';
togglePlugin('geolibre-plugin-geoeditor', true);

```

See the [plugins guide](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/plugins.md) for expected UI behavior.

## Systematic Troubleshooting Checklist

Follow this ordered flow when diagnosing GeoLibre issues:

1. **Clear cache / hard refresh** — Eliminates stale bundle problems
2. **Check Network panel** — Confirm [`main.js`](https://github.com/opengeos/GeoLibre/blob/main/main.js) and plugin bundles load successfully
3. **Verify store state** — Use `window.__GEOLIBRE_STORE__.getState()` to inspect `layers` and `plugins` slices
4. **Refresh failing live layers** — Manually trigger refresh and check inline error messages
5. **Confirm desktop build for saves** — Check Tauri app is running, not browser version
6. **Recover from autosave** — Accept IndexedDB recovery prompt if available

## Key Source Files

| Functionality | File Path | Purpose |
|---------------|-----------|---------|
| Project (de)serialization | [`packages/core/src/project.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/project.ts) | `projectFromStore` and `parseProject` for [`.geolibre.json`](https://github.com/opengeos/GeoLibre/blob/main/.geolibre.json) handling |
| Store-MapLibre sync | [`packages/map/src/MapController.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/map/src/MapController.ts) | `syncLayers` method reconciles store state with map rendering |
| Plugin registration | [`packages/plugins/src/index.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/index.ts) | Built-in and external plugin loading |
| Plugin lifecycle | [`apps/geolibre-desktop/src/hooks/usePlugins.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/hooks/usePlugins.ts) | Activation state management |

## Summary

- **Stale browser cache** is the most common cause of mysterious GeoLibre behavior—always hard refresh first
- **Layer loading** depends on `MapController.syncLayers` correctly reconciling store state with MapLibre; inspect `window.__GEOLIBRE_STORE__.getState().layers` when debugging
- **Project saving** is **desktop-only**—requires Tauri build with writable filesystem access
- **Plugin activation** fails silently when cached; verify bundle loading and store `plugins` slice state
- **Autosave to IndexedDB** provides recovery path for unexpected browser closures

## Frequently Asked Questions

### Why does my layer show an error icon in the Layers panel?

The source URL failed to fetch. Check the URL in the layer's refresh configuration, then press **Refresh now** to retry. Error messages appear inline next to the layer entry according to the [layers documentation](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/layers.md).

### Why is the Save button greyed out in GeoLibre?

You are running the **web build**. Native filesystem saving requires the **Tauri desktop application**. Download and launch the desktop build, then save creates a [`.geolibre.json`](https://github.com/opengeos/GeoLibre/blob/main/.geolibre.json) file directly. The browser version only supports download-based export.

### How do I check if a plugin is actually activated?

Open the browser console and run `console.log(window.__GEOLIBRE_STORE__.getState().plugins)`. Active plugins show `active: true` with their ID. If missing, the plugin bundle failed to load—check the Network tab for 404 errors or stale cache issues.

### Can I recover work after accidentally closing GeoLibre?

Yes, if autosave was enabled. GeoLibre writes snapshots to **IndexedDB** every few seconds. On next launch, a *Recover unsaved work?* prompt appears when a newer snapshot exists. Accept to restore the last autosaved state.