MyCATApache/Mycat-Server · error · ObjectAccessException

No such field .

Error message

No such field ${className}.${fieldName}

What it means

FieldDictionary.field looks up a Field by name (and optionally declaring class) via reflection and throws ObjectAccessException when no matching field exists on the class. This is XStream-style reflection machinery used during object (de)serialization of config beans.

Solutions

  1. Correct the field/element name in the XML to match an actual field on the class
  2. Add the missing field to the target class (or a @XStreamAlias-style mapping) if the XML format is canonical
  3. Check for version skew: regenerate old config files to match the current class definitions

Example fix

<!-- before: class User has no field 'userName' -->
<user><userName>bob</userName></user>
<!-- after -->
<user><name>bob</name></user>
Defensive patterns

Strategy: try-catch

Validate before calling

boolean has = false;
for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
  try { c.getDeclaredField(name); has = true; break; } catch (NoSuchFieldException ignored) {}
}
if (!has) throw new IllegalArgumentException("no field " + cls.getName() + "." + name);

Try / catch

try { return dictionary.field(cls, name); } catch (ObjectAccessException e) { log.warn("field {} missing on {}, using default", name, cls.getName()); return null; }

Prevention

When it happens

Trigger: Calling field(cls, name) or field(cls, name, definedIn) with a field name that does not exist on cls or any of its superclasses up to definedIn; typically during XML unmarshalling when an XML element/attribute name has no corresponding Java field.

Common situations: XML config contains an element/attribute renamed or misspelled relative to the Java bean; class was refactored (field renamed/removed) while old XML files still reference the old name; version mismatch between config files and library classes.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/8fff527aa559a7cd. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/config/util/FieldDictionary.java:73

     * for the field named 'name' inside the class cls. If definedIn is
     * different than null, tries to find the specified field name in the
     * specified class cls which should be defined in class definedIn (either
     * equals cls or a one of it's superclasses)
     * 
     * @param cls
     *            the class where the field is to be searched
     * @param name
     *            the field name
     * @param definedIn
     *            the superclass (or the class itself) of cls where the field
     *            was defined
     * @return the field itself
     */
    public Field field(Class<?> cls, String name, Class<?> definedIn) {
        Map<?, Field> fields = buildMap(cls, definedIn != null);
        Field field = fields.get(definedIn != null ? new FieldKey(name, definedIn, 0) : name);
        if (field == null) {
            throw new ObjectAccessException("No such field " + cls.getName() + "." + name);
        } else {
            return field;
        }
    }

    private Map<?, Field> buildMap(Class<?> cls, boolean tupleKeyed) {
        final String clsName = cls.getName();
        if (!nameCache.containsKey(clsName)) {
            synchronized (keyCache) {
                if (!nameCache.containsKey(clsName)) { // double check
                    final Map<String, Field> keyedByFieldName = new HashMap<String, Field>();
                    final Map<FieldKey, Field> keyedByFieldKey = new OrderRetainingMap<FieldKey, Field>();
                    while (!Object.class.equals(cls)) {
                        Field[] fields = cls.getDeclaredFields();
                        if (JVMInfo.reverseFieldDefinition()) {
                            for (int i = fields.length >> 1; i-- > 0;) {
                                final int idx = fields.length - i - 1;
                                final Field field = fields[i];

View on GitHub (pinned to 65f8d8beb7)