OtterMind/Chat2DB · critical · IllegalStateException

Failed to load ai config from

Error message

Failed to load ai config from 

What it means

Thrown as IllegalStateException('Failed to load ai config from ' + storagePath) by AiModelConfigServiceImpl.loadFromDisk in the catch(Exception) when reading the persisted AI config JSON fails. This runs at construction/startup, so a corrupt config store can block the AI subsystem from initializing. The wrapped exception carries the root cause (parse error or IOException).

Source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/ai/AiModelConfigServiceImpl.java:392

    private synchronized void loadFromDisk() {
        if (!Files.exists(storagePath)) {
            return;
        }
        try {
            StorageData data = objectMapper.readValue(storagePath.toFile(), StorageData.class);
            Map<Long, List<AiModelConfig>> loadedConfigMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(data.getConfigs())) {
                data.getConfigs().forEach(config -> {
                    config.setApiKey(decryptApiKey(config.getApiKey()));
                    Long userId = defaultValue(config.getUserId(), 0L);
                    loadedConfigMap.computeIfAbsent(userId, key -> new ArrayList<>()).add(config);
                });
            }
            userConfigMap.clear();
            userConfigMap.putAll(loadedConfigMap);
        } catch (Exception e) {
            throw new IllegalStateException("Failed to load ai config from " + storagePath, e);
        }
    }

    private synchronized void persistToDisk() {
        try {
            Files.createDirectories(storagePath.getParent());
            StorageData data = new StorageData();
            List<AiModelConfig> all = userConfigMap.values().stream()
                    .flatMap(List::stream)
                    .map(this::encryptedCopy)
                    .collect(Collectors.toList());
            data.setConfigs(all);
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(storagePath.toFile(), data);
        } catch (IOException e) {
            throw new IllegalStateException("Failed to persist ai config to " + storagePath, e);
        }
    }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Back up and remove the corrupt config store file so loadFromDisk starts empty (configs are then re-saved on next save).
  2. Make persistToDisk atomic (write temp then ATOMIC_MOVE) to prevent half-written stores on crash.
  3. Add @JsonIgnoreProperties(ignoreUnknown=true) to StorageData/AiModelConfig for forward-compatible deserialization across upgrades.
  4. Inspect the wrapped exception cause to distinguish JSON corruption from an IO error.

Example fix

// before: direct write, corruptible on crash
objectMapper.writerWithDefaultPrettyPrinter().writeValue(storagePath.toFile(), data);

// after: atomic + tolerant
objectMapper.writerWithDefaultPrettyPrinter().writeValue(tmp.toFile(), data);
Files.move(tmp, storagePath, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
// and on the DTOs:
@JsonIgnoreProperties(ignoreUnknown = true)
public class StorageData { ... }
Defensive patterns

Strategy: try-catch

Try / catch

try {
    aiConfigService = /* load */;
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to load ai config from")) {
        Path store = extractPathFrom(e); // parse storagePath from message
        backupAndQuarantine(store);      // move aside the corrupt store
        aiConfigService = /* retry load with empty store */;
    } else throw e;
}

Prevention

When it happens

Trigger: The ai config storage file (storagePath, the persisted model-config store) exists but objectMapper.readValue cannot deserialize it: truncated/corrupt JSON from a crashed persistToDisk, a schema change to StorageData/AiModelConfig the stored file does not match, or an IOException reading the file.

Common situations: Process was killed during persistToDisk leaving a half-written config file; the file was manually edited; an upgrade changed AiModelConfig fields (e.g. a new required field) so stored configs no longer bind; the config store is on a failing/unmounted volume.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/5664d89dfede619d. Report an issue: GitHub.