I’m trying to implement resourceMapper for a Node that can retrieve resource metadata for any resource (objects and endpoints are named the same, “resource” refers to both) to construct inputs for the selected resource when operation is create or update. Both resource and operation are statically defined properties. There is a property – fields – that is configured to use resourceMapper (and its typeOptions configuration includes resourceMapper.resourceMapperMethod and resourceMapper.mode), and I’ve configured a method in methods.resourceMapping (called getResourceSchema) that: (1) graps the resource and operation fields’ values as set by the user and verifies the operation is a create or update; (2) retrieves the resource-metadata for the selected resource; (3) return a flat array of field objects (where each object contains an id, displayName, type, and required value) to be passed back to the resourceMapper in fields.
So, as far as I can tell, the backend of this is doing what it should do. But for some reason, no matter how many ways I work this, in the UI, selecting a resource and “create” or “update” as the operation doesn’t render anything; it just says there’s no fields.
Am I missing something, here?
I’ve been trying to get this thing to work for like a week. I found a couple similar issue, but nothing that described the specific issue I’m seeing, and I’m beginning to wonder if I’m trying to do something that just isn’t possible. For context, I’m a seasoned Python developer and I’ve got some experience with JS/TS, along with a few other languages, but this is my first time getting “down and dirty” with n8n beyond spinning up an out-of-box-ready solution.
Hey, I have gone through the same pain before and I can tell you this is actually a very common issue with resourceMapper that the docs do not explain well enough.
The first thing I would check is your return value inside getResourceSchema. You mentioned you are returning a flat array of field objects but that is most likely the problem. The method does not want a plain array, it expects an object that wraps the array like this: return the fields inside a fields key. So instead of returning the array directly, you return an object where fields is that array. This one thing alone causes the no fields UI state for most people and n8n gives you zero error about it which makes it incredibly frustrating to debug.
The second thing to double check is that each field object inside that array has all the required keys. Id, displayName, required, defaultMatch, canBeUsedToMatch and type all need to be present. If any of these are missing n8n silently skips the field without telling you.
Also be careful with the type values you are using. Only a specific set of values are accepted like string, number, boolean, dateTime, time, object, options and array. If your metadata is returning something outside of that list the field gets dropped silently again.
Third thing is your property definition for fields itself. Make sure the default value has both mappingMode and value inside it. And make sure you have the fieldWords block with singular and plural defined even though it looks optional, skipping it causes weird behavior.
Fourth, confirm your displayOptions on the fields property exactly matches the resource and operation values as strings. If there is even a small mismatch in casing or spelling the whole mapper stays hidden.
And lastly make sure your method is sitting inside methods.resourceMapping and not inside methods.loadOptions. These two are different and n8n will not find the method if it is in the wrong place.
If you want to share your current property definition and the method code I can take a look and tell you exactly where it is breaking.
Hi @robby.emslie Welcome! @moosa is right about the { fields: [...] } wrapper but the other piece nobody mentioned is loadOptionsDependsOn in your typeOptions — without it n8n won’t re-call getResourceSchema when resource or operation changes, so you get “no fields” every time. also each field object needs display: true or the UI hides it. here’s the property shape that works:
and your method return should look like { fields: [{ id: 'name', displayName: 'Name', type: 'string', required: true, display: true, defaultMatch: false, canBeUsedToMatch: true }] } — the display: true is what actually makes fields render in the UI.
Thank you, everyone! This is a lot more than I was expecting. I’m flying solo on this build and swung to rounding out some other functionality that’s more critical over the last few days. I definitely missed a few important details based on the above, so will commence dealing with them this week. I just wanted to say thank you for taking the time to respond. I’ll update this post after I’ve gone through the above and confirm (or not) that we’re in good shape. Thank you!