nocobase/nocobase · error

[file-manager] no linked or default storage provided

Error message

[file-manager] no linked or default storage provided

What it means

uploadFile needs a storage configuration to write the file to. It looks up the storages cache by storageName; if none matches, it falls back to the storage flagged as default. If neither exists, no destination is defined, so it throws. This typically happens before any file bytes are written.

Source

Thrown at packages/plugins/@nocobase/plugin-file-manager/src/server/server.ts:200

    const data = await this.uploadFile({ storageName: name, subPath, filePath });
    return await collectionRepository.create({ values: { ...data, ...values }, transaction });
  }

  parseStorage(instance) {
    return this.app.environment.renderJsonTemplate(instance.toJSON());
  }

  async uploadFile(options: UploadFileOptions) {
    const { storageName, subPath, filePath, documentRoot } = options;

    if (!this.storagesCache.size) {
      await this.loadStorages();
    }
    const storages = Array.from(this.storagesCache.values());
    const cachedStorage = storages.find((item) => item.name === storageName) || storages.find((item) => item.default);

    if (!cachedStorage) {
      throw new Error('[file-manager] no linked or default storage provided');
    }

    const storage = {
      ...cachedStorage,
      options: { ...(cachedStorage.options || {}) },
      path: resolveStoragePath(cachedStorage.path, subPath),
    };

    const fileStream = fs.createReadStream(filePath);

    if (documentRoot) {
      storage.options['documentRoot'] = documentRoot;
    }

    const StorageType = this.storageTypes.get(storage.type);
    const storageInstance = new StorageType(storage);

    if (!storageInstance) {

View on GitHub (pinned to fa42722fef)

Solutions

  1. Mark one storage configuration as default in the file-manager storage settings (or pass an existing storageName explicitly).
  2. Pass a storageName that matches an existing, enabled storage record exactly.
  3. Ensure the storage collection record exists and loadStorages has run (restarting the app reloads the cache).
  4. Fix the collection's storage option to reference an existing storage name.

Example fix

// before
await app.pm.get('file-manager').uploadFile({ storageName: 'local-backup', filePath }); // not configured
// after: use the actual storage name or configure default
await app.pm.get('file-manager').uploadFile({ storageName: 'local', filePath });
Defensive patterns

Strategy: validation

Validate before calling

const storages = Array.from(fileManager.storagesCache.values());
const ok = (storageName && storages.some(s => s.name === storageName)) || storages.some(s => s.default);
if (!ok) throw new Error('Configure a default storage or pass a valid storageName');

Type guard

const hasUsableStorage = (fm: any, name?: string): boolean =>
  !!Array.from(fm.storagesCache.values()).find((s: any) => s.name === name || s.default);

Try / catch

try {
  await fileManager.uploadFile(opts);
} catch (err) {
  if (err.message.includes('no linked or default storage provided')) {
    // configure a default storage and retry once after loadStorages()
    await fileManager.loadStorages();
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling uploadFile({ storageName: 'xxx', filePath, ... }) where 'xxx' is not in the storages cache AND no storage has default: true; or not passing storageName at all (or a file record/collection without a linked storage) when there is no default storage configured.

Common situations: Fresh install where the default storage record was never created or was disabled; storage name typo; storages cache stale — storage added in another instance without a reload; a file collection's storage option points to a deleted storage.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/6262d6db9f81eaf7. Report an issue: GitHub.