nocobase/nocobase · error

Unsupported association or no usable accessor on ${this.repo

Error message

Unsupported association or no usable accessor on ${this.repository['association']}

What it means

Plain Error thrown by associateRecords as the fallback branch: the repository's association exposes none of the expected accessors (addMultiple, add, set). The message interpolates `this.repository['association']` so the unsupported association object is shown. It indicates the association type/accessors are not what the importer expects.

Source

Thrown at packages/plugins/@nocobase/plugin-action-import/src/server/services/xlsx-importer.ts:613

      throw new Error('Missing accessors or source model.');
    }

    if ((accessors as MultiAssociationAccessors).addMultiple) {
      // For hasMany, belongsToMany
      await sourceModel[(accessors as MultiAssociationAccessors).addMultiple](targets, options);
    } else if ((accessors as MultiAssociationAccessors).add) {
      // Also works for hasMany / belongsToMany
      await Promise.all(
        targets.map((target) => sourceModel[(accessors as MultiAssociationAccessors).add](target, options)),
      );
    } else if (accessors.set) {
      // set accessor(hasOne, belongsTo)
      if (targets.length > 1) {
        throw new Error('Cannot associate multiple records to a single-valued relation.');
      }
      await sourceModel[accessors.set](targets[0], options);
    } else {
      throw new Error(`Unsupported association or no usable accessor on ${this.repository['association']}`);
    }
  }

  renderErrorMessage(error) {
    let message = error.message;
    if (error.parent) {
      message += `: ${error.parent.message}`;
    }

    return message;
  }
  trimString(str: string) {
    if (typeof str === 'string') {
      return str.trim();
    }

    return str;
  }

View on GitHub (pinned to fa42722fef)

Solutions

  1. Verify the import runs on a RelationRepository for a standard relation type (hasMany/belongsToMany/hasOne/belongsTo).
  2. Read the interpolated association value in the message to see which association was actually resolved.
  3. Fix the relation configuration so Sequelize generates add/set accessors (association must be defined on the model).
  4. Update/align datasource plugin versions if accessors() API changed.

Example fix

// before
throw new Error(`Unsupported association or no usable accessor on ${this.repository['association']}`); // association undefined
// after
// configure the relation first:
db.collection({ name: 'users', fields: [{ type: 'belongsTo', name: 'org', target: 'orgs' }] });
Defensive patterns

Strategy: type-guard

Validate before calling

const assoc = (repository as any)?.['association'];
if (!assoc) throw new Error('Repository is not an association repository');

Type guard

function isRelationRepository(r: any): r is RelationRepository {
  return r instanceof RelationRepository && !!r['association'];
}

Try / catch

try {
  await repository.performInsert({ values }, ctx);
} catch (e) {
  if (e.message.startsWith('Unsupported association')) {
    console.error('Resolved association:', e.message); // inspect and fix relation config
  }
  throw e;
}

Prevention

When it happens

Trigger: Repository association is undefined or of a type without standard Sequelize accessors — e.g. repository not an association repository, custom repository overriding accessors(), or association misconfigured so neither add/addMultiple nor set exists.

Common situations: Custom relation/repository implementations lacking Sequelize accessor methods; importing through the wrong repository path; datasource plugin version mismatch where accessors() shape changed.

Related errors


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